/*
 * tcu_can.cpp
 *
 *  Created on: 2019-4-26
 *      Author: root
 */

#include "protocol_can.h"
#include "protocol_offset.h"
#include "tcu_can.h"
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <string.h>
#include "app_debug_can.h"
#include "utils.h"

#define CCU_VERSION_V2_3

//#include "ret.h"
//#include "app_debug.h"
//#include "tools.h"
//#include "utils.h"
//



Para_Can  a_can;
Para_Can * gpcan_para=&a_can;
libcan_t g_can[GUN_NUM];
OverTimeErr overTimeTable[GUN_NUM][14];
SendPara sendpara[GUN_NUM];
u8 fac31=0;
//
//
//
MultFrame  multFrame[GUN_NUM];
start_mx g_u3[GUN_NUM];
end_mx  g_u4[GUN_NUM];
BackResult myorder;
char _tmp_print_str[128];
//收集多帧数据
Cha_TcuInstruction cha2tcu_tab[] = {
		{0x01, 0x02, 0, 4, 250,   5, 	(char*)"充电启动帧" }, 	//充电启动帧pf=0x01 0x02
		{0x03, 0x04, 0, 4, 250,   5, 	(char*) "充电停止" },  	//对时 pf=0x03     04 充电停止
		{0x05, 0x06, 0, 6, 500,   5,  	(char*)"对时" },  		//对时 pf=0x05  06
		{0x07, 0x08, 0, 6, 500,   5, 	(char*)"版本校验" },  	//pgn=1792 pf=0x07 08
		{0x09, 0x0a, 0, 6, 500,   5,	(char*)"充电参数" },  	//pf=0x09 0A
		{0x0b, 0x0c, 0, 4, 250,   5,	(char*)"充电服务启停" },  //pf=0x0B 0c
		{0x0d, 0x0e, 0, 4, 250,   5,	(char*) "电子锁控制" },  //pf=0x0d 0xe
		{0x0f, 0x10, 0, 4, 250,   2, 	(char*)"功率控制" },  //pf=0x0f  0x10
		{0x12, 0x11, 1, 4, 250,   4,	(char*)"启动完成帧" },  //pf=0x11  0x12
		{0x14, 0x13, 1, 4, 250,   5,	(char*) "停止完成帧" },  //pf=0x13  0x14 //
		{0x21,    0, 0, 6, 1000,  0, 	(char*)"直流遥测" },  //pf=0x21
		{0x31,    0, 0, 6, 1000,  0, 	(char*)"交流遥测" },  //pf=0x31
		{0x40, 0x41, 1, 6, 1000,  12,	(char*)"心跳" },  //心跳 pf=0x40	 pgn=16384
		{0x51, 0x52, 0, 4, 250,   5, 	(char*)"错误帧" },  //pf=0x51   0x52  协议要求250
		{0x60, 0x61, 0, 6, 1000,  5, 	(char*)"下发配置参数" },  //pf=0x60  0x61//下发配置参数 协议要求500
		{0x95, 0x96, 0, 4,  250,  5,	(char*)"共充设置帧"},

};

int checkver(u8 gunid);
int gotoCHECK_VER(u8 gunid,u8 pf,u8 flag);//设置超时打印/设置返回匹配开始
int sendChargePara(u8 gunid);
int configPara(u8 gunid);
int  FinStartStopBack(u8 gunid,u8 pf);
int setChaTime(u8 gunid);



void finStartCharge_01(u8 gunid,u8 ret,u8 reason)
{
	static start_mx start_auto;
	start_auto.MX1 =0;
	//	start_auto.MX2 = 1;
	start_auto.MX3 = reason;
	start_auto.MX2 = ret;
	start_auto.dc.MX4[0] = 2;
	//start_auto.dc.MX4[1] = 3;
	can_pro_debug("等待控制器充电但出现故障  成功标识 MX2=%d  失败原因MX3=%d\r\n",start_auto.MX2,start_auto.MX3);

//	sprintf(_tmp_print_str,"下发01等待02  成功标识 MX2=%d  失败原因MX3=%d\r\n",start_auto.MX2,start_auto.MX3);
//	gpcan_para->writelog(_tmp_print_str);

	gpcan_para->StartCharge01(gunid,(void*)&start_auto);

//	////解锁指令
//	//		g_can[gunid].state_ctrl=START_CHARGE_FAIL;
//	//		g_re_num_fk[gunid]=0;
//	//		g_can[gunid].ms_fk_send = 0;
//	////解锁指令结束
//	if(reason==0x42 || reason == 0x40)
//	{
//
//
//		if(gpcan_para->can_ver[0] == 0x10 && gpcan_para->can_ver[1] == 0x01)
//			g_can[gunid].stop_reason=0x03;
//		else
//			g_can[gunid].stop_reason=0x01;
//
//		g_can[gunid].state=TCU_STOP_CHARGING;
//		g_can[gunid].curpf=TCU_CMD_CHARGE_STOP;
//		g_can[gunid].curpos = TableSearch(g_can[gunid].curpf, (u8*) cha2tcu_tab,
//				sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);
//		g_can[gunid].ms_cur_send = cha2tcu_tab[g_can[gunid].curpos].dly;
//	}
//	else{
//		g_can[gunid].state=TCU_READY;
//		g_can[gunid].curpf = 0;
//	}

	return;
}
void finStartCharge_f(u8 gunid,u8 reason)//WAIT_CHARGEING1 收到11 重复发送12,大约5s
{
	static start_mx start_auto;
	start_auto.MX1 =0;
	//	start_auto.MX2 = 1;
	start_auto.MX3 = reason;
	start_auto.MX2 = 1;
	start_auto.dc.MX4[0] = 2;
	//start_auto.dc.MX4[1] = 3;
	can_pro_debug("等待控制器充电但出现故障  MX1= %d  MX2=%d  MX3=%d\r\n",start_auto.MX1,start_auto.MX2,start_auto.MX3);

//	sprintf(_tmp_print_str,"等待控制器11出现故障  成功标识 MX2=%d  失败原因MX3=%d\r\n",start_auto.MX2,start_auto.MX3);
//	gpcan_para->writelog(_tmp_print_str);
	gpcan_para->finStartCharge(gunid,(void*)&start_auto);

//	////解锁指令
//	//		g_can[gunid].state_ctrl=START_CHARGE_FAIL;
//	//		g_re_num_fk[gunid]=0;
//	//		g_can[gunid].ms_fk_send = 0;
//	////解锁指令结束
//	if(reason==0x42 || reason == 0x40)
//	{
//
//
//		if(gpcan_para->can_ver[0] == 0x10 && gpcan_para->can_ver[1] == 0x01)
//			g_can[gunid].stop_reason=0x03;
//		else
//			g_can[gunid].stop_reason=0x01;
//
//		g_can[gunid].state=TCU_STOP_CHARGING;
//		g_can[gunid].curpf=TCU_CMD_CHARGE_STOP;
//		g_can[gunid].curpos = TableSearch(g_can[gunid].curpf, (u8*) cha2tcu_tab,
//				sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);
//		g_can[gunid].ms_cur_send = cha2tcu_tab[g_can[gunid].curpos].dly;
//	}
//	else{
//		g_can[gunid].state=TCU_READY;发送版本校验CHECK_VER gunid=
//		g_can[gunid].curpf = 0;
//	}

	return;
}
void finStopCharge_f(u8 gunid,u8 reason)
{
	static end_mx end;
	end.MX1 = reason;
	end.MX2 = 0;
	can_pro_debug("can中断或控制器返回停止超时向主控返回结果 reason=%x\r\n", reason);
	gpcan_para->finStopCharge(gunid, (void*) &end);
//	g_can[gunid].state = TCU_READY;
//	g_can[gunid].curpf = 0;
//	can_pro_debug1("can中断或控制器返回超时变为待机状态 ");
//	if(reason == 0x40)
//	{
//		g_can[gunid].curpf=TCU_CMD_CHARGE_STOP;
//		if(gpcan_para->can_ver[0] == 0x10 && gpcan_para->can_ver[1] == 0x01)
//			g_can[gunid].stop_reason=0x03;
//		else
//			g_can[gunid].stop_reason=0x01;
//
//		g_can[gunid].state=TCU_STOP_CHARGING;
//		g_can[gunid].curpos = MidSplitTableSearch(g_can[gunid].curpf, (u8*) cha2tcu_tab,sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);
//		can_pro_debug1("can中断或控制器返回超时向控制器发送停止充电命令 reason=%x\r\n",reason);
//	}
//	else{
//		g_can[gunid].state=TCU_READY;
//		g_can[gunid].curpf = 0;
//		can_pro_debug1("can中断或控制器返回超时变为待机状态 ");
//	}


}
void clearErrCode(u8 gunid,int interval)
{
	int i;
	int num=ARRAY_LEN(overTimeTable[0]);
	for(i=0;i< num;i++)
	{
		if(overTimeTable[gunid][i].rest_ms_err==0)
			continue;
		printf("错误帧剩余发送时间   overTimeTable[gunid][i].rest_ms_err=%d\r\n",overTimeTable[gunid][i].rest_ms_err);
	    overTimeTable[gunid][i].rest_ms_err-=interval;
		printf("1111错误帧剩余发送时间   i=%d  overTimeTable[gunid][i].rest_ms_err=%d gunid=%d\r\n",i,overTimeTable[gunid][i].rest_ms_err,gunid);
	    if( overTimeTable[gunid][i].rest_ms_err<=0)
	    {

			printf("2222错误帧剩余发送时间   overTimeTable[gunid][i].rest_ms_err=%d  g_can[gunid].err_code_all=%d\r\n",overTimeTable[gunid][i].rest_ms_err,g_can[gunid].err_code_all);
	    	overTimeTable[gunid][i].rest_ms_err=0;
	    	g_can[gunid].err_code_all &= ~(1<<overTimeTable[gunid][i].err_code);
			printf("3333错误帧剩余发送时间   overTimeTable[gunid][i].rest_ms_err=%d  g_can[gunid].err_code_all=%d\r\n",overTimeTable[gunid][i].rest_ms_err,g_can[gunid].err_code_all);
			if(g_can[gunid].state == CHECK_VER)
						checkver(gunid);
	    }
	}
}

void _addtime_(int interval)
{
	int i;
	u8 gunnum=gpcan_para->gunnum;
	for (i = 0; i < gunnum; i++) {
		g_can[i].ms_heart_recv += interval;//上次收到心跳后到现在的毫秒
		g_can[i].ms_heart_send += interval;//上次发送心跳后到现在的毫秒
		g_can[i].ms_cur_send += interval;//本次状态下发送帧到现在的毫秒
		g_can[i].ms_cur_recv += interval;//本次状态下等待接收到现在的毫秒
		g_can[i].ms_yc_send += interval;//摇测最后发送到现在的毫秒
		g_can[i].ms_yc_recv += interval;//摇测最后接收到现在的毫秒
		g_can[i].ms_yx_recv += interval;//摇信最后接收到现在的毫秒
		g_can[i].ms_err_send+=interval;//
		g_can[i].ms_comm_recv+=interval;
		if(g_can[i].ms_comm_recv>COMM_CUTOFF*1000)
			g_can[i].comm_cutoff=1;
		clearErrCode(i,interval);
	}


}

u8 getChargeState(u8 gunid)
{
	u8 charge_state=0;

	if(gpcan_para->type==DC)
	{

		charge_state=a_can.data2main->gun[gunid].yx_data.yx_dc_pf22[1]&0x03;
		if(charge_state>0)
			printf("直流摇信pf22=%d",charge_state);

	}
	else if(gpcan_para->type==AC)
	{
		charge_state=a_can.data2main->gun[gunid].yx_data.yx_ac_pf32[1]&0x03;
	}
	return charge_state;

}
u8 get_gun_err(u8 gunid) {
	u8 tabid;
	u8 offset;
	u8 err_code = 0;
	tabid = 1;
	offset = 2;
	if(gpcan_para->type==DC)
	    err_code = (a_can.data2main->gun[gunid].yx_data.yx_dc_pf22[tabid] >> offset) & 0x01;
	else
		err_code = (a_can.data2main->gun[gunid].yx_data.yx_ac_pf32[tabid] >> offset) & 0x01;
	return err_code;
}

u8 get_gun_conn_state(u8 gunid)//获得充电枪连接状态
{
	u8 conn_state;
	u8 tabid;
	u8 offset;
	if(a_can.type==DC)
	{
		tabid=DC_IND_CONNECT_CAR_OFFSET/8+1;
		offset=DC_IND_CONNECT_CAR_OFFSET%8;
		conn_state=(a_can.data2main->gun[gunid].yx_data.yx_dc_pf22[tabid]>>offset)&0x01;
	}
	else if(a_can.type==AC)
	{
		tabid=AC_IND_CONNECT_SWITCH_OFFSET/8+1;
		offset=AC_IND_CONNECT_SWITCH_OFFSET%8;

		conn_state=(a_can.data2main->gun[gunid].yx_data.yx_ac_pf32[tabid]>>offset)&0x01;
	}

	if(conn_state==0)
		conn_state=1;
	else
		conn_state=0;
	printf("获得充电枪连接状态 conn_state=%d\r\n",conn_state);
	return conn_state;
}
void sendFrameToMain(u8 port,GW_Can *pgwsend)
{
	//can_pro_debug("通过主控发送到控制器！！！port=%d  pf=%x  %.*a",port,pgwsend->pf,pgwsend->lendata,pgwsend->pdata);
	gpcan_para->send2cha(port,pgwsend);
	can_pro_debug("TCU - > CCU : port=%d  pf=%x  %.*a",port,pgwsend->pf,pgwsend->lendata,pgwsend->pdata);
}

//void clearOverTime(u8 gunid, u8 pf)
//{
//	u16 pos=0;
//
//	pos=TableSearch(pf, (u8*)&overTimeTable[gunid], sizeof(OverTimeErr),ARRAY_LEN(overTimeTable[0]),1);
//	if(pos!=0xffff)
//	{
//		//			printf("幸运找到的pf=%x",pf);
//		overTimeTable[gunid][pos].overtime=0;
//	}
//			printf("##libcan##清空时间,找不到的pf=%x",pf);//注意 少了pf=0x23
//	}
//}
//void Set_UnsetOverTime(u8 gunid,u8 pf,u8 flag)
//	else{
//{
//	u16 pos;
//    pos=TableSearch(pf, (u8*)&overTimeTable[gunid], sizeof(OverTimeErr),ARRAY_LEN(overTimeTable[0]),1);
//    overTimeTable[gunid][pos].ifset=flag;
//
//}

u8  Set_UnsetOverTime(u8 gunid,u8 pf)
{
	u16 pos;
    printf("\r\nSet_UnsetOverTime00000  pf=%x\r\n",pf);
    pos=TableSearch(pf, (u8*)&overTimeTable[gunid], sizeof(OverTimeErr),ARRAY_LEN(overTimeTable[0]),1);
    if(pos==0xffff)
    {
    	printf("\r\n没找到需要超时的  pf=%x\r\n",pf);
    	return 0;
    }
    printf("\r\nSet_UnsetOverTime222222222222222  pos=%d  pf=%x\r\n",pos,pf);
    overTimeTable[gunid][pos].rest_ms_err=DURATION_ERR*1000;
    g_can[gunid].err_code_all|=(1<<overTimeTable[gunid][pos].err_code);
    printf("\r\nSet_UnsetOverTime1111111111111111   g_can[gunid].err_code_all=%d\r\n",g_can[gunid].err_code_all);
    return 1;

}

////复位监控 type=1 充电超时复位  2:系统监控复位
//void ResetMonitor(u8 gunid, u8 type)
//{
//	if(type == 1){
//		Set_UnsetOverTime(gunid,CTL_CMD_STOP_RESPONSE,0);
//		Set_UnsetOverTime(gunid,CTL_CMD_START_RESPONSE,0);
//		Set_UnsetOverTime(gunid,CTL_STATUS_STARTUP_COMPLETE,0);
//		Set_UnsetOverTime(gunid,CTL_STATUS_STOP_COMPLETE,0);
//
//		clearOverTime(gunid,CTL_CMD_START_RESPONSE);
//		clearOverTime(gunid,CTL_CMD_STOP_RESPONSE);
//		clearOverTime(gunid,CTL_STATUS_STARTUP_COMPLETE);
//		clearOverTime(gunid,CTL_STATUS_STOP_COMPLETE);
//	}
//	else if(type == 2){
//		Set_UnsetOverTime(gunid,CTL_CMD_CHARGE_PARAM_CONFIRM,0);
//		clearOverTime(gunid,CTL_CMD_CHARGE_PARAM_CONFIRM);
//
//		Set_UnsetOverTime(gunid,CTL_CMD_CHARGE_CONFIG_INFO_FEEDBACK,0);
//		clearOverTime(gunid,CTL_CMD_CHARGE_CONFIG_INFO_FEEDBACK);
//
//		Set_UnsetOverTime(gunid,CTL_DATA_AC_TELEMETRY,0);
//		Set_UnsetOverTime(gunid,CTL_DATA_AC_TELESIGNAL_1,0);
//		Set_UnsetOverTime(gunid,CTL_DATA_DC_TELEMETRY,0);
//		Set_UnsetOverTime(gunid,CTL_DATA_DC_TELESIGNAL_1,0);
//		clearOverTime(gunid,CTL_DATA_AC_TELEMETRY);
//		clearOverTime(gunid,CTL_DATA_AC_TELESIGNAL_1);
//		clearOverTime(gunid,CTL_DATA_DC_TELEMETRY);
//		clearOverTime(gunid,CTL_DATA_DC_TELESIGNAL_1);
//
//	}
//}
int countGunno1(u8 port,u8 chaaddr,u8 frame_gunid)
{
	int i=0;

	//    for(i=0;i<2;i++)
	//    {
	//    	 printf("\n\n port=%d  cha_addr=%x   tcu_addr=%x  frame_gunno=%d\n",gpcan_para->pgun_info[i].port,gpcan_para->pgun_info[i].cha_addr,gpcan_para->pgun_info[i].tcu_addr,gpcan_para->pgun_info[i].frm_gunno);
	//    }
	for(i=0;i<gpcan_para->gunnum;i++)
	{
		if(gpcan_para->pgun_info[i].port==port  && gpcan_para->pgun_info[i].cha_addr==chaaddr && gpcan_para->pgun_info[i].frm_gunno==frame_gunid)
		{
			return i;
		}
		//        else if(gpcan_para->pgun_info[i].port==port)
		//        {
		//        	printf("\n\n出现了奇观的事情，不应当！！！！！！！！！！！！！！！frame_gunid=%d  %d\n\n", gpcan_para->pgun_info[i].frm_gunno,frame_gunid);//发送到CANDLL err err
		//        	printf("\n\n出现了奇观的事情，不应当！！！！！！！！！！！！！！！port=%d\n\n",port);
		//
		//        }
	}


	for(i=0;i<gpcan_para->gunnum;i++)
	{
		printf("\n\n port=%d  cha_addr=%x   tcu_addr=%x  frame_gunno=%d\n",gpcan_para->pgun_info[i].port,gpcan_para->pgun_info[i].cha_addr,gpcan_para->pgun_info[i].tcu_addr,gpcan_para->pgun_info[i].frm_gunno);
	}
	printf("\n\n111111出现了奇观的事情，不应当！！！！！！！！！！！！！！！port=%d chaaddr=%x  frame_gunid=%d\n\n",port,chaaddr,frame_gunid);

	return -1;
}
int countGunno(u8 port,u8 chaaddr,u8 pf,u8 *data,u8 *gunid)
{
	int i,ret;
	u8 frame_gunid;
	u8 frameid = data[0];

	if(frameid==1)
	{
		frame_gunid = data[4];
		for(i=0;i<gpcan_para->gunnum;i++)
		{
			can_pro_debug("接收到第一包数据：port=%d  %d  cha_addr=%d   %d  frm_gunno=%d %d",gpcan_para->pgun_info[i].port,port, gpcan_para->pgun_info[i].cha_addr,chaaddr,gpcan_para->pgun_info[i].frm_gunno,frame_gunid);

			if(gpcan_para->pgun_info[i].port==port  && gpcan_para->pgun_info[i].cha_addr==chaaddr && gpcan_para->pgun_info[i].frm_gunno==frame_gunid)
			{
				if(multFrame[i].frameIndex>0)
				{
					printf("多帧未能完成，控制器开始重新发送，所以重新记录！！！\r\n");
				}
				*gunid=i;
				return 1;
			}
			//		         else接收到中间数据,有不相同 gunid=
			//		         {
			//		        	 can_pro_debug("接收到第一包数据,有不相同");
			//		         }
		}
	}
	else
	{

		// 	can_pro_debug("接收到第一包数据：port=%d  %d  cha_addr=%d   %d  frm_gunno=%d %d  pf=%x  %x",gpcan_para->pgun_info[i].port,port, gpcan_para->pgun_info[i].cha_addr,chaaddr,gpcan_para->pgun_info[i].frm_gunno,frame_gunid);
		for (i = 0; i < gpcan_para->gunnum; i++) {
			if (multFrame[i].port == port
					&& multFrame[i].chaaddr == chaaddr
					&& multFrame[i].priPF == pf
					&& multFrame[i].frameIndex == (frameid - 1)) {
				can_pro_debug("收到正确的帧序号 frameid=%d  \n", frameid);
				multFrame[i].frameIndex += 1;
				*gunid=i;
				ret = 2;
				if (multFrame[i].frameIndex == multFrame[i].frameSumCount) {
					ret = 3;
					printf("收到最后一帧  multFrame[i].frameIndex=%d\r\n",
							multFrame[i].frameIndex);
				}
				return ret;
			} else if (multFrame[i].port == port && multFrame[i].chaaddr == chaaddr && frameid == multFrame[i].frameIndex) {
				printf(" pf=0x%x, 处理到第%d帧,貌似发生了重复发送现象data[0]=%d！！！\r\n",
						pf, multFrame[i].frameIndex, frameid);
				return -2;
			}
			//			else {
			//
			//				can_pro_debug(
			//						"接收到中间数据,有不相同 gunid=%d  port=%d  %d  chaddr=%x %x\r\n",i,multFrame[i].port,port , multFrame[i].chaaddr,chaaddr);
			//				//return -2;;
			//			}

		}
	}

	return -3;
}



//int countGunno1(u8 port,u8 chaaddr,u8 frame_gunid)
//{
//	int i=0;
//    for(i=0;i<gpcan_para->gunnum;i++)
//    {
//        if(gpcan_para->pgun_info[i].port==port  && gpcan_para->pgun_info[i].cha_addr==chaaddr && gpcan_para->pgun_info[i].frm_gunno==frame_gunid)
//	         {
//        	        return i;
//	         }
//    }
//
//    printf("没找到枪号！！！！！！！！！！！！！！！！！！！port=%d\n\n",port);
//    return -1;
//}
//int countGunno(u8 port,u8 chaaddr,u8 pf,u8 *data,u8 *gunid)
//{
//	int i,ret;
//	u8 frame_gunid;
//	 u8 frameid=data[0];
//	if(frameid==1)
//	{
//
//		frame_gunid=data[4];
//	    for(i=0;i<gpcan_para->gunnum;i++)
//	    {
//	    	can_pro_debug("接收到第一包数据：port=%d  %d  cha_addr=%d   %d  frm_gunno=%d %d",gpcan_para->pgun_info[i].port,port, gpcan_para->pgun_info[i].cha_addr,chaaddr,gpcan_para->pgun_info[i].frm_gunno,frame_gunid);
//
//		         if(gpcan_para->pgun_info[i].port==port  && gpcan_para->pgun_info[i].cha_addr==chaaddr && gpcan_para->pgun_info[i].frm_gunno==frame_gunid)
//		         {
//						if(multFrame[i].frameIndex>0)
//						{
//							printf("多帧未能完成，控制器开始重新发送，所以重新记录！！！\r\n");
//						}
//						*gunid=i;
//		        	    return 1;
//		         }
//		         else
//		         {
//		        	 can_pro_debug("接收到第一包数据,有不相同");
//		         }
//	    }
//	}
//	else
//	{
//
//    	//can_pro_debug("接收到第一包数据：port=%d  %d  cha_addr=%d   %d  frm_gunno=%d %d  pf=%x  %x",gpcan_para->pgun_info[i].port,port, gpcan_para->pgun_info[i].cha_addr,chaaddr,gpcan_para->pgun_info[i].frm_gunno,frame_gunid);
//		for (i = 0; i < gpcan_para->gunnum; i++) {
//			if (multFrame[i].port == port && multFrame[i].chaaddr == chaaddr
//					&& multFrame[i].priPF == pf
//					&& multFrame[i].frameIndex == (frameid - 1)) {
//				printf("收到正确的帧序号 frameid=%d  \n", frameid);
//				multFrame[i].frameIndex += 1;
//				*gunid=i;
//				ret = 2;
//				if (multFrame[i].frameIndex == multFrame[i].frameSumCount) {
//					ret = 3;
//					printf("收到最后一帧  multFrame[i].frameIndex=%d\r\n",
//							multFrame[i].frameIndex);
//				}
//				return ret;
//			} else if (multFrame[i].port == port && multFrame[i].chaaddr == chaaddr && frameid == multFrame[i].frameIndex) {
//				printf(" 处理到第%d帧,貌似发生了重复发送现象data[0]=%d port=%d  addr=%x！！！\r\n",
//						multFrame[i].frameIndex, frameid,port,chaaddr);
//				return -1;
//			} else {
//
//				can_pro_debug(
//						"接收到中间数据,有不相同 frameid=%d  gunid=%d pf=%x\r\n",frameid,gunid,pf);//
//			  can_pro_debug("接收到中间数据,有不相同 ：port=%d  %d  cha_addr=%d   %d  frm_gunno=%d %d  pf=%x  %x",gpcan_para->pgun_info[i].port,port, gpcan_para->pgun_info[i].cha_addr,chaaddr,gpcan_para->pgun_info[i].frm_gunno,frameid);
//
//				//return -2;;
//			}
//
//		}
//	}
//
//    return -3;
//}

//int countGunno(u8 port,u8 chaaddr,u8 frm_gunno)
//{
//	int i;
//    for(i=0;i<gpcan_para->gunnum;i++)
//    {
//	         if(gpcan_para->pgun_info[i].port==port  && gpcan_para->pgun_info[i].cha_addr==chaaddr  && gpcan_para->pgun_info[i].frm_gunno==frm_gunno)
//	         {
//	        	return i;
//	         }
//    }
//    return -1;
//}
int canCollectMultiFrameData(u8* index,u8 port,u8 chaaddr,u8 pf, u8* data)
{
	int  k;// j=0xff,
	int ret=0;
	int num;
	u16 checkSum=0;
	u8 gunid;

	//	for(i=0;i<gpcan_para->gunnum;i++)
	//	{
	//		if(multFrame[i].priPF==0 && j==0xff)
	//		{
	//			j=i;//记录第一个空闲的位置
	//	//		printf("记录一个空闲的位置 j=%d\r\n",j);
	//		}
	ret=countGunno(port,chaaddr,pf,data,&gunid);

	if(ret<0)
	{

		//       	printf("can err err err !!!!!!!!!!!!!!!!!! port =%d  gunid=%d\n",port,gunid);
		if(ret==-1)
			goto end;
		else
			return -1;
	}


	//
	//    	if((multFrame[i].port==port) && (multFrame[i].chaaddr==chaaddr) && multFrame[i].priPF==pf)
	//		{
	//			if(data[0] == 1)
	//			{
	//				if(multFrame[i].frameIndex>0)
	//				{
	//					printf("多帧未能完成，控制器开始重新发送，所以重新记录！！！\r\n");
	//				}
	//                ret=1;
	//			//	break;
	//		    }
	//			else if(data[0] ==multFrame[i].frameIndex+1)
	//			{
	//              printf("收到正确的帧序号 data[0] =%d  ",data[0] );
	//				multFrame[i].frameIndex += 1;
	//				num=8;
	//				ret=2;
	//				if(multFrame[i].frameIndex==multFrame[i].frameSumCount)
	//				{
	//					ret=3;
	//					num=multFrame[i].lastFrameDataLen+1;
	//				   printf("收到最后一帧  multFrame[i].frameIndex=%d num=%d\r\n",multFrame[i].frameIndex,num);
	//				}
	//
	//
	//			//	break;
	//
	//			}
	//			else if(data[0] ==multFrame[i].frameIndex)
	//			{
	//		    	printf(" 处理到第%d帧,貌似发生了重复发送现象data[0]=%d！！！\r\n",multFrame[i].frameIndex,data[0]);
	//				return -1;
	//			}
	//			else
	//			{
	//
	//				printf("err err err err err err err err err err err err err err err err\r\n");
	//				ret= -2;
	//			}
	//		}
	//        i=countGunno(port,chaaddr);
	//	}
	//
	//	    if(ret==0)
	//	    {
	//	    	i=j;
	//	    }
	can_pro_debug("111查询出来的枪号  port=%d gunid=%d frm_no=%d\n", port,gunid,data[0]);
	if ( ret == 1) {


		multFrame[gunid].frm_gunno = data[4];
		can_pro_debug("查询出来的枪号  port=%d gunid=%d frm_no=%d\n", port,gunid,data[0]);
		multFrame[gunid].tcu_gunno = gunid;//id;
		multFrame[gunid].priPF = pf;
		multFrame[gunid].chaaddr = chaaddr;
		multFrame[gunid].frameIndex = 1;
		multFrame[gunid].port = port;
		//	printf("第一帧数据=%d\r\n", id);

		multFrame[gunid].frameSumCount = data[1]; //总帧
		multFrame[gunid].dataLen = data[3] << 8 | data[2]; //总有效字节
		if (multFrame[gunid].frameSumCount < 2 || multFrame[gunid].dataLen < 8) {
			return -6;
		}
		multFrame[gunid].lastFrameDataLen = (multFrame[gunid].dataLen - 4) % 7; //最后一帧的字节数
		if (multFrame[gunid].lastFrameDataLen > 5) {
			return -7;
		}
		multFrame[gunid].dataIndex = 0;
		num = 8;

	}

	if (ret>0) {
		if(ret!=3)
			num=8;
		else
			num=multFrame[gunid].lastFrameDataLen+1;
		can_pro_debug("将有效数据保存 gunid=%d\r\n",gunid);
		for (k = 1; k < num; k++) {
			multFrame[gunid].multiFrameData[multFrame[gunid].dataIndex++] = data[k]; //将有效数据保存
		}
		if (ret == 3) {
			can_pro_debug("多帧收到的全部数据 len=%d  buf=%.*a",multFrame[gunid].dataIndex,multFrame[gunid].dataIndex,&multFrame[gunid].multiFrameData[0]);

			if (multFrame[gunid].dataIndex != (multFrame[gunid].dataLen+3)) {

				can_pro_debug("最后一帧接收完毕，但收到字节不对multFrame[i].dataIndex=%d  multFrame[i].dataLen =%d\r\n",multFrame[gunid].dataIndex, multFrame[gunid].dataLen+3);
				ret = -3;
				goto end;
			}
			for(k=0;k<=multFrame[gunid].dataIndex;k++)
			{
				checkSum+=multFrame[gunid].multiFrameData[k];
				//	      printf("最后一帧接收完毕,校验位  %x\r\n",checkSum);

			}
			//     printf("最后一帧接收完毕,校验位=%d  %x\r\n",checkSum,checkSum);
			if (data[multFrame[gunid].lastFrameDataLen + 1] != (checkSum & 0xff)
					|| (data[multFrame[gunid].lastFrameDataLen + 2]
							 != ((checkSum >> 8) & 0xff))) {
				can_pro_debug("最后一帧接收完毕，校验位错了 data[multFrame[i].lastFrameDataLen + 1]  =%x   data[multFrame[i].lastFrameDataLen + 1]  =%x checkSum=%x\r\n"
						,data[multFrame[gunid].lastFrameDataLen + 1],data[multFrame[gunid].lastFrameDataLen + 2],checkSum);
				ret = -4;
			}
			else
				can_pro_debug("最后一帧接收完毕，校验位正确\r\n");
		}
		//		multFrame[i].frameIndex++;
	}
	end:	if(ret<0)
	{
		printf("end err err err err!!!!!\n");
		multFrame[gunid].dataIndex = 0;
		multFrame[gunid].frameIndex = 0;
		multFrame[gunid].frameSumCount = 0;
		multFrame[gunid].dataLen = 0;
		multFrame[gunid].lastFrameDataLen = 0;
		multFrame[gunid].priPF = 0;
		memset(&multFrame[gunid].multiFrameData[0],0,128);

	}

	*index=gunid;
	return ret;


}
int canDCNwData(unsigned char *data, unsigned short len,
		int gunid)
{
	//	u8 xxx[]={0x0a,0x3f,0x00,0x00,0x00,0x00,0x00
	//			,0x05,0x00,0x01,0x02,0x00,0x00,0x00
	//			,0x00,0x00,0x00,0x00,0x00,0x00,0x00
	//			,0x00,0x00,0x02,0x02,0x01,0x00,0x02
	//			,0x18,0x20,0x08,0x09,0x4c,0x1d,0xd0
	//			,0x07,0x00,0x00,0x00,0xd7,0x08,0xd6
	//			,0x08,0xdb,0x08,0x2b,0x03,0x00,0x00
	//			,0xe6,0x03,0x00,0x00,0x2b,0x03,0x00
	//			,0x00,0x59,0x01,0x00,0x00,0x00,0x00
	//			,0x00,0x01,0x00,0x21,0x06};
	//	u8 xxx[]={0x01,0x0a,0x3f,0x00,0x00,0x00,0x00,0x00
	//			,0x02,0x05,0x00,0x01,0x02,0x00,0x00,0x00
	//			,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00
	//			,0x04,0x00,0x00,0x02,0x02,0x01,0x00,0x02
	//			,0x05,0x18,0x20,0x08,0x09,0x4c,0x1d,0xd0
	//			,0x06,0x07,0x00,0x00,0x00,0xd7,0x08,0xd6
	//			,0x07,0x08,0xdb,0x08,0x2b,0x03,0x00,0x00
	//			,0x08,0xe6,0x03,0x00,0x00,0x2b,0x03,0x00
	//			,0x09,0x00,0x59,0x01,0x00,0x00,0x00,0x00
	//			,0x0a,0x00,0x01,0x00,0x21,0x06};

	//	u8 xxx[]={0x0b,0x44,0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00
	//			,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
	//			,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
	//			,0x12,0x09,0x28,0x09,0x23,0x09,0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07
	//			,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
	//			,0x00,0x00,0x2c,0x01,0x00,0x00,0x00,0x00	};//0x0b,0x44,0x00,
	//	data=xxx;
	//	len=sizeof(xxx);
	can_pro_debug("ABC三相电压A:37-38 B:39-40 C 41-42  电流A:43-46 B:47-50 C:51-54  有功总电度55-58  AB线间电压59-60 ");
	//ABC三相电压A:37-38 B:39-40 C 41-42  电流A:43-46 B:47-50 C:51-54  有功总电度55-58  AB线间电压59-60      低字节在前
	gpcan_para->data2main->gun[gunid].yc_data.dc.MX[19]  =(data[40] << 8) | data[39];//交流输出 A 相电压
	gpcan_para->data2main->gun[gunid].yc_data.dc.MX[20] = (data[42] << 8) | data[41];// 交流输出 B 相电压
	gpcan_para->data2main->gun[gunid].yc_data.dc.MX[21] = (data[44] << 8) | data[43];// 交流输出 C 相电压
	gpcan_para->data2main->gun[gunid].yc_data.dc.MX[22] = (data[46] << 8) | data[45];//交流输出 A 相电流
	gpcan_para->data2main->gun[gunid].yc_data.dc.MX[23] = (data[50] << 8) | data[49];//交流输出 B 相电流
	gpcan_para->data2main->gun[gunid].yc_data.dc.MX[24] = (data[54] << 8) | data[53];//交流输出 C 相电流
	gpcan_para->data2main->gun[gunid].yc_data.dc.MX[25] = (data[62] << 8) | data[61];//AB线间电压
	gpcan_para->data2main->gun[gunid].yc_data.dc.MX[26] = (data[58] << 8) | data[57];//有功总电度
	gpcan_para->data2main->gun[gunid].yc_data.dc.MX[27] = (data[60] << 8) | data[59];//有功总电度

	can_pro_debug1("A电压=%d  B电压 =%d  C电压=%d   线间电压=%d",gpcan_para->data2main->gun[gunid].yc_data.dc.MX[19]
	                ,gpcan_para->data2main->gun[gunid].yc_data.dc.MX[20]
	                ,gpcan_para->data2main->gun[gunid].yc_data.dc.MX[21]
	                ,gpcan_para->data2main->gun[gunid].yc_data.dc.MX[25]);

	can_pro_debug1("A电流=%d  B电流 =%d  C电流=%d ",gpcan_para->data2main->gun[gunid].yc_data.dc.MX[22]
	               ,gpcan_para->data2main->gun[gunid].yc_data.dc.MX[23]
	               ,gpcan_para->data2main->gun[gunid].yc_data.dc.MX[24]);

	can_pro_debug1("有功总电度=%d  有功总电度 =%d  ",gpcan_para->data2main->gun[gunid].yc_data.dc.MX[26]
	                ,gpcan_para->data2main->gun[gunid].yc_data.dc.MX[27]);
	return 0;
}

//遥测数据解析
int canDCTelemetryData(unsigned char *data, unsigned short len,int gunid)
{
	short temp;

	if(gpcan_para->can_ver[0] == 0x10 && gpcan_para->can_ver[1] == 0x01){

		if(len != 30 && len !=34){
			printf("##libcan## DC telemetry data len error  len=%d! 10 01\n",len);
			return 1;
		}
		//gpcan_para->

		can_pro_debug1("dll打印遥测数据 gunid1=%d 数据包长度 len= %d  frame=%.*a", gunid, len, len, data);
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[0] = (data[5] << 8) | data[4];//充电输出电压
		temp= (data[7] << 8) | data[6];
		temp-=4000;
		if(temp<0)
			temp = -temp;
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[1] =temp;//充电输出电流

		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[2] =data[8];// SOC
		printf(" gunid ===%d  lllllll======%d  %d %d\n",gunid,gpcan_para->data2main->gun[gunid].yc_data.dc.MX[1],gpcan_para->data2main->gun[gunid].yc_data.dc.MX[0],gpcan_para->data2main->gun[gunid].yc_data.dc.MX[2]);
		if(g_can[gunid].state==WAIT_CHARGEING2 || g_can[gunid].state==WAIT_CHARGEING3)
		{
			if(data[8]==0)
				gpcan_para->data2main->gun[gunid].yc_data.dc.MX[2] =1;// SOC
		}
		else
		{
			gpcan_para->data2main->gun[gunid].yc_data.dc.MX[2] =0;
		}
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[3] = data[9]-50;//电池组最低温度
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[4] = data[10]-50;//电池组最高温度
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[5] = (data[12] << 8) | data[11];//单体电池最高电压
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[6] = (data[14] << 8) | data[13];//单体电池最低电压
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[7] = data[15]-50; //充电机环境温度
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[8] = (data[17] << 8) | data[16];//充电导引电压
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[9] = (data[19] << 8) | data[18];//BMS 需求电压
		temp=(data[21] << 8) | data[20];
		temp-=4000;
		if(temp<0)
			temp = -temp;
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[10] =temp ;// BMS 需求电流
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[11] = data[22]; // 充电模式
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[12] = (data[24] << 8) | data[23];  //BMS 充电电压测量值
		temp=(data[26] << 8) | data[25];
		temp-=4000;
		if(temp<0)
			temp = -temp;
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[13] =temp ;//BMS 充电电流测量值
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[14] = (data[28] << 8) | data[27];//估算剩余充电时间
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[15] = data[29]-50;//充电接口温度探头 1 温度(接口 1 DC+)
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[16] = data[30]-50;//充电接口温度探头 2 温度(接口 1 DC-)
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[17] = data[31]-50;//充电接口温度探头 3 温度(接口 2 DC+)
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[18] = data[32]-50;//充电接口温度探头 4 温度(接口 2 DC+)

#ifdef CCU_VERSION_V2_3
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[19] = data[33];	  //电表当前读数，分辨率0.001kWh/bit,0Kw偏移量，如果电表接在CCU那么发0
#endif
	}

	else if(gpcan_para->can_ver[0] == 0x03 && gpcan_para->can_ver[1] == 0x01){
		if (len != 22) {
			printf("##libcan## DC telemetry data len error!  len=%d!   03 01\n  ",len);//diff_DateTime_Sec
			gpcan_para->can_ver[0] =0x10;
			gpcan_para->can_ver[1] = 0x01;

			return 1;
		}
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[0] = (data[5] << 8)|data[4];
		temp= (data[7] << 8) | data[6];
		temp-=4000;
		if(temp<0)
			temp = -temp;
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[1] =temp;

		temp = (data[9] << 8) | data[8];
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[2] = 	temp;
		if(g_can[gunid].state==WAIT_CHARGEING1  || g_can[gunid].state==WAIT_CHARGEING2){
			if(temp==0)
				gpcan_para->data2main->gun[gunid].yc_data.dc.MX[2] =1;// SOC
		}
		else{
			gpcan_para->data2main->gun[gunid].yc_data.dc.MX[2] =0;
		}

		temp =  (data[11] << 8) | data[10];
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[3] = temp-50;

		temp =  (data[13] << 8) | data[12];
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[4] =temp-50;

		temp =  (data[15] << 8) | data[14];
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[5] =temp;

		temp =  (data[17] << 8) | data[16];
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[6] = temp	;

		temp =  (data[19] << 8) | data[18];
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[7] = temp - 50	;

		temp =  (data[21] << 8) | data[20];
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[8] =temp;
	}

	gpcan_para->outyc(gunid,(void*)&gpcan_para->data2main->gun[gunid].yc_data);//.ac.MX[0]


	return 0;
}

int canACTelemetryData(unsigned char *data, unsigned short len,
		int gunid) {

	//	if(len != 24) {
	//		printf("##libcan## AC telemetry data len error  len=%d!\n",len);
	//		return ERROR_INPARA;
	//	}
	candll_debug("从控制器收到的遥测数据 %.*a 长度=%d",len,data,len);
	gpcan_para->data2main->gun[gunid].yc_data.ac.MX[0] = (data[5] << 8) | data[4];//充电输出 A 相电压
	gpcan_para->data2main->gun[gunid].yc_data.ac.MX[1] = (data[7] << 8) | data[6];//充电输出 B 相电压
	gpcan_para->data2main->gun[gunid].yc_data.ac.MX[2] = (data[9] << 8) | data[8];//充电输出 C 相电压
	gpcan_para->data2main->gun[gunid].yc_data.ac.MX[3] = (data[11] << 8) | data[10];//充电输出 A 相电流
	gpcan_para->data2main->gun[gunid].yc_data.ac.MX[4] = (data[13] << 8) | data[12];//充电输出 B 相电流
	gpcan_para->data2main->gun[gunid].yc_data.ac.MX[5] = (data[15] << 8) | data[14];//充电输出 C 相电流
	gpcan_para->data2main->gun[gunid].yc_data.ac.MX[6] = (data[17] << 8) | data[16];//充电导引电压

	//ltp change 2018-12-24 自适应V1.10协议
	if(gpcan_para->can_ver[0] == 0x10 && gpcan_para->can_ver[1]==0x01){
		gpcan_para->data2main->gun[gunid].yc_data.ac.MX[7] = (data[19] << 8) | data[18];//输出 PWM 占空比
		gpcan_para->data2main->gun[gunid].yc_data.ac.MX[8] = data[20]-50;//充电接口温度探头 1 温度(接口 1 DC+)
		gpcan_para->data2main->gun[gunid].yc_data.ac.MX[9] = data[21]-50;//充电接口温度探头 1 温度(接口 1 DC+)
		gpcan_para->data2main->gun[gunid].yc_data.ac.MX[10] = data[22]-50;//充电接口温度探头 1 温度(接口 1 DC+)
		gpcan_para->data2main->gun[gunid].yc_data.ac.MX[11] = data[23]-50;//充电接口温度探头 1 温度(接口 1 DC+)
	}


	gpcan_para->outyc(gunid,(void*)&gpcan_para->data2main->gun[gunid].yc_data);//.ac.MX[0]
	return 0;
}
//启动充电完成帧数据解析
int canStartUpChargeDataParse(unsigned char *data,
		unsigned short len, int gunIndex) {
	u8 ret=0;
	int i = 0;
	int length=4;
	can_pro_debug("启动完成帧 %.*a",len,data);

	//解析数据
#ifndef VERSION_103_20151225

	g_u3[gunIndex].MX1 = data[length++];
	g_u3[gunIndex].MX2 = data[length++];
	g_u3[gunIndex].MX3 = data[length++];
	g_u3[gunIndex].dc.MX4[0] = data[length++];
	g_u3[gunIndex].dc.MX4[1] = data[length++];
	g_u3[gunIndex].dc.MX4[2] = data[length++];
	g_u3[gunIndex].dc.MX5[0] = data[length++];
	g_u3[gunIndex].dc.MX5[1] = data[length++];
	g_u3[gunIndex].dc.MX5[2] = data[length++];
	g_u3[gunIndex].dc.MX6 = data[length++];
	g_u3[gunIndex].dc.MX7 = data[length++];
	g_u3[gunIndex].dc.MX8 = data[length++];
	g_u3[gunIndex].dc.MX9  = data[length] | (data[length+1]<<8); length+=2;
	g_u3[gunIndex].dc.MX10 = data[length] | (data[length+1]<<8); length+=2;
	g_u3[gunIndex].dc.MX11 = data[length] | (data[length+1]<<8); length+=2;
	g_u3[gunIndex].dc.MX12 = data[length] | (data[length+1]<<8); length+=2;
	g_u3[gunIndex].dc.MX13 = data[length] | (data[length+1]<<8); length+=2;
	g_u3[gunIndex].dc.MX14 = data[length] | (data[length+1]<<8); length+=2;
	g_u3[gunIndex].dc.MX15 = data[length] | (data[length+1]<<8); length+=2;
	g_u3[gunIndex].dc.MX16 = data[length] | (data[length+1]<<8); length+=2;
	g_u3[gunIndex].dc.MX17 = data[length] | (data[length+1]<<8); length+=2;
	g_u3[gunIndex].dc.MX18 = data[length] | (data[length+1]<<8); length+=2;
	g_u3[gunIndex].dc.MX19 = data[length] | (data[length+1]<<8); length+=2;
	g_u3[gunIndex].dc.MX20 = data[length] | (data[length+1]<<8); length+=2;

	for(i=0; i<17; i++)
		g_u3[gunIndex].dc.MX21[i] = data[length+i];
	length+=17;

	can_pro_debug("111启动完成帧 %.*a",len,data);
	//成功标识 和 BMS握手结果
	FinStartStopBack(gunIndex,TCU_STATUS_STARTUP_COMPLETE_RESPONSE);
	usleep(5);
	if(data[5] != 0 ) {// || data[7] != 0
		can_pro_debug("控制器启动失败！！！标志=%d  原因=%d",g_u3[gunIndex].MX2,g_u3[gunIndex].MX3);
		g_u3[gunIndex].MX3+=100;

		if (g_can[gunIndex].state == WAIT_CHARGE) {
			g_can[gunIndex].state = TCU_READY;
			can_pro_debug("000dll控制器启动失败！！！g_can[%d].state=%d", gunIndex,
					g_can[gunIndex].state);
			gpcan_para->finStartCharge(gunIndex,(void*)&g_u3[gunIndex]);//启动失败
			can_pro_debug("dll控制器启动失败！！！g_can[%d].state=%d", gunIndex,
					g_can[gunIndex].state);
		}
		//		sprintf(_tmp_print_str,"dll控制器启动失败！！！g_can[%d].state=%d\n", gunIndex,
		//					g_can[gunIndex].state);
		//		gpcan_para->writelog(_tmp_print_str);
		//		if (g_can[gunIndex].state == WAIT_CHARGE)
		//			g_can[gunIndex].state = WAIT_CHARGEING1;//启动完成多帧包已经全部接收完毕
		//	启动充电成功
		//   g_can[gunIndex].state = TCU_READY;;

		ret = 1;
	}
	else
	{
		can_pro_debug("控制器启动成功！！！g_can[%d].state=%d", gunIndex,
				g_can[gunIndex].state);

		//		sprintf(_tmp_print_str,"dll控制器启动成功！！！g_can[%d].state=%d\n", gunIndex,
		//					g_can[gunIndex].state);
		//		gpcan_para->writelog(_tmp_print_str);
		if (g_can[gunIndex].state == WAIT_CHARGE) {
			g_can[gunIndex].state = WAIT_CHARGEING1;
			can_pro_debug("000dll控制器启动成功！！！g_can[%d].state=%d", gunIndex,
					g_can[gunIndex].state);
			gpcan_para->finStartCharge(gunIndex, (void*) &g_u3[gunIndex]);  //启动成功
			can_pro_debug("dll控制器启动成功！！！g_can[%d].state=%d", gunIndex,
					g_can[gunIndex].state);
		}
		//		else if(g_can[gunIndex].state !=WAIT_CHARGEING)
		//		{
		//	        printf("在不应当充电的地方收到启动完成帧,进行终止充电g_can[%d].state=%d\r\n",gunIndex,g_can[gunIndex].state);
		//            g_can[gunIndex].curpf=TCU_CMD_CHARGE_STOP;
		//    		g_can[gunIndex].stop_reason=0;
		//	        g_can[gunIndex].state=TCU_STOP_CHARGING;
		//	        printf("在不应当充电的地方收到启动完成帧,进行终止充电\r\n");
		//		}
	}

	//	g_can[gunIndex].curpf = 0;

#endif

#ifdef VERSION_103_20151225


	u3.dc.MX1 = data[4];
	u3.dc.MX2 = data[5];
	u3.dc.MX4[0] = data[6];
	u3.dc.MX4[1] = data[7];
	u3.dc.MX4[2] = data[8];
	u3.dc.MX5[0] = data[9];
	u3.dc.MX5[1] = data[10];
	u3.dc.MX5[2] = data[11];
	u3.dc.MX6 = data[12];
	u3.dc.MX7 = data[13];
	u3.dc.MX8 = data[14];
	u3.dc.MX9 = (data[16] << 8)
			| data[15];
	u3.dc.MX10 = (data[18] << 8)
			| data[17];
	u3.dc.MX11 = (data[20] << 8)
			| data[19];
	u3.dc.MX12 = (data[22] << 8)
			| data[21];
	=gunIndex1+port;
	u3.dc.MX13 = (data[24] << 8)
			| data[23];
	u3.dc.MX14 = (data[26] << 8)
			| data[25];
	u3.dc.MX15 = (data[28] << 8)
			| data[27];
	u3.dc.MX16 = (data[30] << 8)
			| data[29];
	u3.dc.MX17 = (data[32] << 8)
			| data[31];
	u3.dc.MX18 = (data[34] << 8)
			| data[33];
	u3.dc.MX19 = (data[36] << 8)
			| data[35];

	//成功标识 和 BMS握手结果
	if (data[5] != 0) {
		gpcan_para->finStartCharge(gunIndex,(void*)&u3);//启动失败
		return ERROR_FAIL;
	} else
		gpcan_para->finStartCharge(gunIndex,(void*)&u3);//启动成功

#endif
	return ret;//ERROR_OK;
}

//交流充电中收到停止完成帧  实际接收到的645返回len
int ACFinStop(u8 gunid,unsigned char *data) {
	//停止完成应答帧
	static end_mx u4;
	u4.MX1 = data[1];
	u4.MX2 = data[2];
	printf("交流充电中收到停止完成帧\n");
	gpcan_para->finStopCharge(gunid,(void*)&u4);
	FinStartStopBack(gunid,TCU_STATUS_STOP_COMPLETE_RESPONSE);
	return 0;
}

int canStopChargeDataParse(unsigned char *data, int gun_index) {
	g_u4[gun_index].MX1 = data[4];
	g_u4[gun_index].MX2 = data[5];
	g_u4[gun_index].dc.MX3 = data[6];
	g_u4[gun_index].dc.MX4[0] = data[7];
	g_u4[gun_index].dc.MX4[1] = data[8];
	g_u4[gun_index].dc.MX5 = data[9];
	g_u4[gun_index].dc.MX6 = data[10];
	g_u4[gun_index].dc.MX7 = data[11]| (data[12] << 8);
	g_u4[gun_index].dc.MX8 = data[13] | (data[14] << 8);
	g_u4[gun_index].dc.MX9 = data[15];
	g_u4[gun_index].dc.MX10 = data[16];
	g_u4[gun_index].dc.MX11 = data[17] & 0x03;
	g_u4[gun_index].dc.MX12 = (data[17] >> 2) & 0x03;
	g_u4[gun_index].dc.MX13 = (data[18]) & 0x03;
	g_u4[gun_index].dc.MX14 = (data[18] >> 2) & 0x03;
	g_u4[gun_index].dc.MX15 = (data[19]) & 0x03;
	g_u4[gun_index].dc.MX16 = (data[19] >> 2) & 0x03;
	g_u4[gun_index].dc.MX17 = (data[20]) & 0x03;
	g_u4[gun_index].dc.MX18[0] = (data[20] >> 2) & 0x01;
	g_u4[gun_index].dc.MX18[1] = (data[20] >> 3) & 0x01;
	g_u4[gun_index].dc.MX18[2] = (data[20] >> 4) & 0x01;
	g_u4[gun_index].dc.MX18[3] = (data[20] >> 5) & 0x01;
	g_u4[gun_index].dc.MX18[4] = (data[20] >> 6) & 0x01;
	g_u4[gun_index].dc.MX18[5] = (data[20] >> 7) & 0x01;
	g_u4[gun_index].dc.MX19 = data[21] & 0x03;
	g_u4[gun_index].dc.MX20 = data[22] & 0x03;
	g_u4[gun_index].dc.MX21 = (data[22] >> 2) & 0x03;
	g_u4[gun_index].dc.MX22 = (data[23]) & 0x03;
	g_u4[gun_index].dc.MX23 = (data[23] >> 2)& 0x03;
	g_u4[gun_index].dc.MX24 = (data[23] >> 4)& 0x03;
	g_u4[gun_index].dc.MX25 = (data[24]) & 0x03;
	g_u4[gun_index].dc.MX26[0] = (data[24] >> 2) & 0x01;
	g_u4[gun_index].dc.MX26[1] = (data[24] >> 3) & 0x01;
	g_u4[gun_index].dc.MX26[2] = (data[24] >> 4) & 0x01;
	g_u4[gun_index].dc.MX26[3] = (data[24] >> 5) & 0x01;
	g_u4[gun_index].dc.MX26[4] = (data[24] >> 6) & 0x01;
	g_u4[gun_index].dc.MX26[5] = (data[24] >> 7) & 0x01;

	can_pro_debug1("向主控报告停止成功或失败  回应停止完成帧 gunid=%d",gun_index);

	//	sprintf(_tmp_print_str,"向主控报告停止成功或失败  回应停止完成帧 gunid=%d\n",gun_index);
	//	gpcan_para->writelog(_tmp_print_str);
	gpcan_para->finStopCharge(gun_index, (void*)&g_u4[gun_index]);//向主控报告启动成功或失败  回应启动完成帧

	FinStartStopBack(gun_index,TCU_STATUS_STOP_COMPLETE_RESPONSE);
	return 0;
}

int saveYxData(unsigned char pf, unsigned char gunid,unsigned char *data,u16 len)
{

	switch(pf)
	{
	case CTL_DATA_DC_TELESIGNAL_1:
		memcpy(gpcan_para->data2main->gun[gunid].yx_data.yx_dc_pf22,data,len);
		break;
	case  CTL_DATA_DC_TELESIGNAL_2:
		memcpy(gpcan_para->data2main->gun[gunid].yx_data.yx_dc_pf23,data,len);
		break;
	case  CTL_DATA_AC_TELESIGNAL_1:
		memcpy(gpcan_para->data2main->gun[gunid].yx_data.yx_ac_pf32,data,len);
		break;
	default:
		break;
	}

	return 0;
}
void ACFinStart(u8 gunid,u8 pf,unsigned char *data)
{

	//ltp change 2018-12-21 保存交流启动完成帧信息
	g_u3[gunid].MX1 = data[1];
	g_u3[gunid].MX2 = data[2];
	g_u3[gunid].MX3 = data[3];

	FinStartStopBack(gunid,TCU_STATUS_STARTUP_COMPLETE_RESPONSE);
	usleep(5);
	if(data[2] != 0 ) {
		printf("##libcan##控制器启动失败！！！标志=%d  原因=%d\n",g_u3[gunid].MX2,g_u3[gunid].MX3);
		//g_u3[gunid].MX3+=100;
		gpcan_para->finStartCharge(gunid,(void*)&g_u3[gunid]);//启动失败
		g_can[gunid].state = WAIT_CHARGEING1;
	}
	else
	{
		candll_debug("##libcan##控制器启动成功！！！g_can[%d].state=%d\n", gunid,
				g_can[gunid].state);
		if (g_can[gunid].state == WAIT_CHARGE) {
			g_can[gunid].state = WAIT_CHARGEING1;

			gpcan_para->finStartCharge(gunid, (void*) &g_u3[gunid]);  //启动成功
			candll_debug("dll控制器启动成功！！！g_can[%d].state=%d", gunid,
					g_can[gunid].state);
		}
	}
	return;
}
int AnalyzeData(u8 gunid,u8 pf,u8 lendata,u8* pdata)
{
	int ret = 0;

	can_pro_debug("收到来自主控的can包 gunid=%d 收到来自主控的can包 pmsg_rev->pf=0x%x   gunid=%d pos=%d",gunid, pf,//正在充电，CAN
			gunid,g_can[gunid].curpos);
	g_can[gunid].ms_comm_recv=0;//>COMM_CUTOFF*1000)
    g_can[gunid].comm_cutoff=0;
	if (g_can[gunid].state == TCU_IDEL) {
		can_pro_debug("暂时不理 g_can[%d].state=%d  pf=%02x",gunid, g_can[gunid].state,pf);
		if(pf == CHA_HEART){
			//	g_can[gunid].heart_over_err = 0;
			g_can[gunid].ms_heart_recv = 0;
			g_can[gunid].state = HEART_BEAT_FIRST;
			can_pro_debug("IDEL状态下收到控制器心跳 重新进行交互 g_can[%d].state=%d  pf=%02x",gunid, g_can[gunid].state,pf);
		}

		return -1;
	}
	///当前状态  curState=
	if(pf==0x22 || pf==0x23)// || pf==0x23)//(pf==0x22 || pf==0x23 || pf==0x20 || pf==0x11 || pf==0x13 || pf==0x15 || pf==0x61  || pf==0x0a || pf==0x08 || pf==0x0d)//|| pf==0x41
	{
		if(gunid==0)
			can_pro_debug("xxxxxxxxxxxxstate=%d pf[%d]=%x  frame=%.*a",g_can[gunid].state,gunid,pf,lendata,pdata);
		else
			can_pro_debug("yyyyyyyyyyyystate=%d pf[%d]=%x  frame=%.*a",g_can[gunid].state,gunid,pf,lendata,pdata);
	}
	if(gunid==1)
		can_pro_debug("11188888888888888888888888888888888   pf=%x\r\n",pf);


	if (g_can[gunid].state == HEART_BEAT_FIRST) {
		g_can[gunid].ms_heart_recv = 0;
		if (pf == CHA_HEART)   //收到控制器心跳
		{
			can_pro_debug("收到来自主控的心跳包,开始版本校验 curState=%d", g_can[gunid].state);
			//			sprintf(_tmp_print_str,"收到来自主控的心跳包,开始版本校验 curState=%d gunid=%d\n", g_can[gunid].state,gunid);
			//			gpcan_para->writelog(_tmp_print_str);

			g_can[gunid].state = CHECK_VER; //返回匹配开始
			checkver(gunid);
			g_can[gunid].ms_cur_recv = 0;
			candll_debug("收到来自主控的心跳包 g_can[%d].state=%d,errcode=%d",gunid, g_can[gunid].state, gpcan_para->data2main->errcode[gunid]);
			g_can[gunid].ms_heart_recv = 0;
			//	g_can[gunid].heart_over_err = 0;
			if((gpcan_para->data2main->errcode[gunid]&(1<<HEART_OVER_ERR)) !=0)
			{

				gpcan_para->data2main->errcode[gunid] &= ~(1<<HEART_OVER_ERR);
			}

		} else {
			candll_debug("等待控制器心跳，暂时不理 g_can[%d].state=%d  pmsg_rev->pf=%x ",gunid,
					g_can[gunid].state, pf);
			//	canDCNwData(pdata, lendata,gunid);
		}
		return -1;
	}
	can_pro_debug("222收到来自主控的can包 pmsg_rev->pf=0x%x   gunid=%d pos=%d", pf,
			gunid,g_can[gunid].curpos);


	switch (pf) {
	case CTL_ERROR_STATUS: {
		candll_debug("收到来自控制器的错误数据包  pf=%x  %.*a", pf, 8, pdata);//收到来自主控的can包
		//		g_can[gunid].state = TCU_IDEL
	}
	ret=-1;
	break;

	case CTL_DATA_DC_TELESIGNAL_1:
	case CTL_DATA_DC_TELESIGNAL_2:
	case CTL_DATA_AC_TELESIGNAL_1:
		g_can[gunid].ms_yx_recv =0;
		if (g_can[gunid].state <= SEND_CHARGE_PARAM) {
			can_pro_debug("还没有完成注册，收到来自控制器的遥信数据包  pf=%x %.*a  g_can[gunid].ms_heart_send=%d",pf,8,pdata,g_can[gunid].ms_heart_send);
			can_pro_debug("当前状态  curState=%d",g_can[gunid].state);
			return -1;
		}
		else
		{
			can_pro_debug("完成注册后，收到来自控制器的遥信数据包  pf=%x %.*a",pf,8,pdata);

			saveYxData(pf,gunid ,pdata, lendata);
			//			if((g_can[gunid].heart_over_err  & (1<<YX_OVER_ERR))==0)
			//			{
			//
			//				g_can[gunid].heart_over_err &= ~(1<<YX_OVER_ERR);
			//			}
			if((gpcan_para->data2main->errcode[gunid]&(1<<YX_OVER_ERR)) !=0)
			{

				gpcan_para->data2main->errcode[gunid] &= ~(1<<YX_OVER_ERR);
				g_can[gunid].ms_yx_recv=0;
			}

			if((pf==0x22 && ( (pdata[1] & 0x03)==2) && g_can[gunid].state>=WAIT_STOP)
					||(pf==0x32 && ((pdata[1]&0x0F)==2) && g_can[gunid].state >= WAIT_STOP))//ltp change 2018-12-25 兼容交流遥信
			{
				g_can[gunid].state = TCU_READY;
			}
			can_pro_debug("完成注册后，收到来自控制器的遥信数据包  pf=%x %.*a gunid=%d",pf,8,gpcan_para->data2main->gun[gunid].yx_data.yx_dc_pf22,gunid);
			gpcan_para->outyx(gunid,
					(void*) &gpcan_para->data2main->gun[gunid].yx_data);  //送数据到主控
			ret=1;
		}
		g_can[gunid].ms_yx_recv =0;
		can_pro_debug("555收到来自主控的can包 pmsg_rev->pf=0x%x   gunid=%d pos=%d g_can[gunid].state=%d", pf,
				gunid,g_can[gunid].curpos,g_can[gunid].state);
		break;
	case CHA_HEART:
		candll_debug("收到来自主控的心跳包 g_can[%d].state=%d", gunid,g_can[gunid].state);
		//	canDCNwData(pdata, lendata, gunid);
		g_can[gunid].ms_heart_recv = 0;
		//	g_can[gunid].heart_over_err = 0;

		//	if(gpcan_para->firm_id != XJ)
		if((gpcan_para->data2main->errcode[gunid]&(1<<HEART_OVER_ERR)) !=0)
		{

			gpcan_para->data2main->errcode[gunid] &= ~(1<<HEART_OVER_ERR);
		}
		//	canDCNwData(pdata, lendata, gunid);
		ret=2;
		break;

	case CTL_CMD_VERSION_CONFIRM://版本校验成功
		if(g_can[gunid].state >= SEND_CHARGE_PARAM){
			ret=3;
			can_pro_debug("收到版本校验应答帧，不处理!  curState=%d",g_can[gunid].state);//第三步：发送对时命令
			break;
		}

		candll_debug("第一步成功：收到版本校验返回 gpcan_para->can_ver %x.%x  gunid=%d  curState=%d"
				,gpcan_para->can_ver[1],gpcan_para->can_ver[0],gunid,g_can[gunid].state);
		//		sprintf(_tmp_print_str,"第一步成功：收到版本校验返回 gpcan_para->can_ver %x.%x  gunid=%d  curState=%d\n"
		//				,gpcan_para->can_ver[1],gpcan_para->can_ver[0],gunid,g_can[gunid].state);
		//		gpcan_para->writelog(_tmp_print_str);
		if(pdata[1]==gpcan_para->can_ver[0] && pdata[2]==gpcan_para->can_ver[1])//与设置相同
		{

			can_pro_debug("第一步成功：收到版本校验返回 ver:%x.%x  state=%d  pf=%x",pdata[2],pdata[1],g_can[gunid].state,TCU_CMD_SEND_CHARGE_PARAM);

		}
		else if((pdata[1]==0x03  && pdata[2]==0x01) ||  (pdata[1]==0x10  && pdata[2]==0x01)  )  //pdata[0]
		{
			gpcan_para->can_ver[0]=pdata[1];
			gpcan_para->can_ver[1]=pdata[2];
		}
		g_can[gunid].state = SEND_CHARGE_PARAM;
		g_can[gunid].ms_cur_recv = 0;
		sendChargePara(gunid);
		ret=4;
		break;
	case CTL_CMD_CHARGE_PARAM_CONFIRM:
		ret=5;
		if(g_can[gunid].state != SEND_CHARGE_PARAM){
			can_pro_debug("收到充电参数校验应答帧，不处理!  curState=%d",g_can[gunid].state);
			break;
		}

		if(pdata[1]==0x00)
		{
			can_pro_debug("第二步成功：收到充电参数返回  curState=%d gpcan_para->can_ver[0]=%x  gpcan_para->can_ver[1] ",g_can[gunid].state,gpcan_para->can_ver[0],gpcan_para->can_ver[1]);
			//			sprintf(_tmp_print_str,"第二步成功：收到充电参数返回gunid=%d  curState=%d gpcan_para->can_ver[0]=%x  gpcan_para->can_ver[1] =%x\n"
			//					,gunid,g_can[gunid].state,gpcan_para->can_ver[0],gpcan_para->can_ver[1]);
			//			gpcan_para->writelog(_tmp_print_str);

			if(gpcan_para->can_ver[0]==0x03 && gpcan_para->can_ver[1]==0x01){

				g_can[gunid].state =TCU_READY;
				g_can[gunid].curpf=0;
				g_can[gunid].ms_cur_send =0;
				g_can[gunid].ms_yc_recv =0;
				g_can[gunid].ms_yx_recv=0;
				can_pro_debug("对于交流桩，使用1.03协议 当前状态=%d  pf=%x",g_can[gunid].state,g_can[gunid].curpf);//第二步成功：收到充电参数返回
			}
			else{
				if(g_can[gunid].state<TCU_SET_TIME)//  CONFIG_INFO_QUERY)
				{
					g_can[gunid].ms_yc_recv =0;
					g_can[gunid].ms_yx_recv=0;
					can_pro_debug("第二步成功：收到充电参数返回 CONFIG_INFO_QUERY gunid=%d",gunid);
					g_can[gunid].state=TCU_SET_TIME;
					g_can[gunid].ms_cur_recv = 0;
					setChaTime(gunid);

				}
			}
		}
		else if(pdata[1]==0x01)
		{
			if(g_can[gunid].state<= SEND_CHARGE_PARAM){
				g_can[gunid].state = CHECK_VER; //返回匹配开始
				checkver(gunid);
				g_can[gunid].ms_cur_recv = 0;
				can_pro_debug("第二步失败：收到充电参数返回  curState=%d",g_can[gunid].state);
			}
		}

		break;
	case CTL_CMD_TIME_SET:
	{
		can_pro_debug("第三步成功：对时命令确认！！！");
		//		sprintf(_tmp_print_str,"第三步成功：对时命令确认！！！\n");
		//		gpcan_para->writelog(_tmp_print_str);
		//		g_can[gunid].state=CONFIG_INFO_QUERY;
		//		g_can[gunid].curpf=TCU_CMD_CHARGE_CONFIG_INFO_QUERY;
		if(g_can[gunid].state<CONFIG_INFO_QUERY)
		{
			g_can[gunid].ms_yc_recv =0;
			g_can[gunid].ms_yx_recv=0;
			can_pro_debug("第三步成功：CTL_CMD_TIME_SET gunid=%d",gunid);
			g_can[gunid].state=CONFIG_INFO_QUERY;
			g_can[gunid].ms_cur_recv = 0;
			configPara(gunid);
		}



	}

	ret=6;
	break;

	//	启动充电指令的返回 - V2.3版本增加即插即充标志
	case CTL_CMD_START_RESPONSE:
		//	{
		//		can_pro_debug("收到充电指令返回！！！！%.*a",8,pdata);
		//		//ltp change 2019-01-07 防止没发启动命令时收到启动应答
		//		if(g_can[gunid].state != TCU_START_CHARGING){
		//			printf("##libcan## recv pf=02 , but break, don't change state, curState=%d\n",g_can[gunid].state);
		//			break;
		//		}
		//
		//		if (pdata[2] == 0) {
		//			can_pro_debug("收到充电指令返回,启动成功！！！！%.*a",8,pdata);
		//			g_can[gunid].state = WAIT_CHARGE;
		//	//		g_can[gunid].curpf = 0;
		//
		//		}
		//		else
		//		{
		//			can_pro_debug("收到充电指令返回,启动失败！！！！%.*a",8,pdata);
		//			if(g_can[gunid].state_ctrl!=START_CHARGE_FAIL)
		//				finStartCharge_f(gunid,pdata[3]);
		//			g_can[gunid].state = TCU_READY;
		//			g_can[gunid].curpf = 0;
		//			g_can[gunid].ms_cur_send = 0;
		//			g_can[gunid].ms_cur_recv = 0;
		//
		//		}
		//	}
	{
		can_pro_debug("收到充电指令返回！！！！%.*a",8,pdata);
		//ltp change 2019-01-07 防止没发启动命令时收到启动应答
		if(g_can[gunid].state != TCU_START_CHARGING){
			printf("##libcan## recv pf=02 , but break, don't change state, curState=%d\n",g_can[gunid].state);
			break;
		}

		if (pdata[2] == 0) {
			can_pro_debug("收到充电指令返回,启动成功！！！！%.*a",8,pdata);
			//			sprintf(_tmp_print_str,"gunid=%d 收到01充电指令返回,启动成功！！！\n",gunid);
			//			gpcan_para->writelog(_tmp_print_str);

			g_can[gunid].state = WAIT_CHARGE;
			finStartCharge_01(gunid,0,0);
			//		g_can[gunid].curpf = 0;
		}
		else
		{
			can_pro_debug("收到充电指令返回,启动失败！！！！%.*a",8,pdata);
			sprintf(_tmp_print_str,"gunid=%d 收到01充电指令返回,启动失败！！！\n",gunid);
			gpcan_para->writelog(_tmp_print_str);

			if(g_can[gunid].state_ctrl!=START_CHARGE_FAIL)
				finStartCharge_01(gunid,1,pdata[3]);
			g_can[gunid].state = TCU_READY;
			g_can[gunid].curpf = 0;
			g_can[gunid].ms_cur_send = 0;
			g_can[gunid].ms_cur_recv = 0;

		}
	}
	ret= 7;
	break;

	case CTL_STATUS_STARTUP_COMPLETE: {
		if(g_can[gunid].state != WAIT_CHARGE){
			printf("11111111111111111111111\r\n");
			printf("##libcan## recv pf=11 , but break, don't change state, curState=%d\n",g_can[gunid].state);
			printf("222222222222222222222222\r\n");
			break;
		}

		if (gpcan_para->type == AC) {
			can_pro_debug("AC启动完成帧已经接收完毕，开始处理！！！！！！！");
			ACFinStart(gunid,pf, pdata);
		} else {
			can_pro_debug("启动完成多帧包已经全部接收完毕，开始处理！！！！！！！gunid=%d",gunid);
			canStartUpChargeDataParse(pdata, lendata, gunid);

		}
		//		g_can[gunid].curpf=TCU_STATUS_STARTUP_COMPLETE_RESPONSE;

		g_can[gunid].ms_cur_recv=0;

	}
	ret=8;
	break;
	case CTL_CMD_STOP_RESPONSE:
	{
		static u8 xx=0;
		xx++;
		can_pro_debug("发送03后收到04 充电结束返回！！！！g_can[gunid].state=%d xx=%d",g_can[gunid].state,xx);
		//		sprintf(_tmp_print_str,"gunid=%d 收到04充电结束返回！！！！g_can[gunid].state=%d xx=%d\n",gunid,g_can[gunid].state,xx);
		//		gpcan_para->writelog(_tmp_print_str);
		if(g_can[gunid].state != TCU_STOP_CHARGING){
			printf("##libcan## recv pf=04,but break, don't change state, curState:%d\n",g_can[gunid].state);
			break;
		}
		if(g_can[gunid].state<WAIT_STOP){
			g_can[gunid].state=WAIT_STOP;
			g_can[gunid].ms_cur_send = 0;
			g_can[gunid].ms_cur_recv = 0;
		}
		g_can[gunid].curpf=0;
		ret=9;
	}
	break;
	case CTL_STATUS_STOP_COMPLETE:
	{
		if(g_can[gunid].state > WAIT_STOP){
			printf("##libcan## recv pf=13 , but break, don't change state, curState:%d\n",g_can[gunid].state);
			break;
		}

		g_can[gunid].state=RESEND_STOP;
		if (gpcan_para->type == DC)
		{
			canStopChargeDataParse(pdata,gunid);
		}
		else if(gpcan_para->type == AC)
		{
			ACFinStop(gunid,pdata);
		}
		g_can[gunid].ms_cur_recv=0;

	}
	ret=10;


	break;

	case CTL_DATA_AC_TELEMETRY:
		g_can[gunid].ms_yc_recv=0;
		candll_debug("交流遥测接收完毕，开始处理！！！！！！！");
		canACTelemetryData(pdata, lendata, gunid);
		if((gpcan_para->data2main->errcode[gunid]&(1<<YC_OVER_ERR)) !=0)
		{

			gpcan_para->data2main->errcode[gunid] &= ~(1<<YC_OVER_ERR);
		}
		ret=11;
		break;
	case CTL_DATA_DC_TELEMETRY:
		g_can[gunid].ms_yc_recv=0;
		candll_debug("遥测多帧包已经全部接收完毕，开始处理！！！！！！！");
		canDCTelemetryData(pdata, lendata, gunid);
		if((gpcan_para->data2main->errcode[gunid]&(1<<YC_OVER_ERR)) !=0)
		{

			gpcan_para->data2main->errcode[gunid] &= ~(1<<YC_OVER_ERR);
		}

		ret=12;
		break;

		//case CTL2TCU_NW_15:
		//	canDCNwData(pdata, lendata, gunid);
		//	ret=13;
		//	break;
	case CTL2TCU_XJ_DC_15:
		//candll_debug("\r\nDC[%d] charger status:0x%x", gunid, pdata[1]);
		ret = 13;
		break;

	case CTL2TCU_XJ_AC_16:
		//candll_debug("\r\nAC[%d] charger status:0x%x", gunid, pdata[1]);
		ret = 13;
		break;

	case CTL_CMD_CHARGE_CONFIG_INFO_FEEDBACK:
		if(g_can[gunid].state != CONFIG_INFO_QUERY)
		{
			printf("##libcan## recv pf=61 , but break, don't change state, curState=%d gunid=%d\n",g_can[gunid].state,gunid);
			break;
		}
		g_can[gunid].ms_yc_recv =0;
		g_can[gunid].ms_yx_recv=0;
		g_can[gunid].err_code_all =0;
		can_pro_debug("第四步 配置参数成功！！！！l  gunid=%d  curState=%d",gunid,g_can[gunid].state);
		//			sprintf(_tmp_print_str,"第四步 配置参数成功！！！！l  gunid=%d  curState=%d\n",gunid,g_can[gunid].state);
		//			gpcan_para->writelog(_tmp_print_str);
		if(g_can[gunid].state<TCU_READY){
			g_can[gunid].state=TCU_READY;
			g_can[gunid].curpf=0;
		}
		ret=14;
		break;
	case CTL_CMD_POWER_ADJUST_FEEDBACK:
	{
		static ctrlpw_bak xx;
		can_pro_debug1("调节功率  调节功率 调节功率 返回%.*a",lendata, pdata);

		if(g_can[gunid].state_ctrl == CTRL_PW_EN)
		{
			g_can[gunid].state_ctrl = CTRL_PW_FIN;

			if(pdata[4]==0)
			{
				can_pro_debug1("功率调节成功！！！！！gunid=%d",gunid);
				xx.result=0;
				xx.ctrlvalue=0;

			}
			else
			{
				can_pro_debug1("功率调节失败！！！！！gunid=%d 失败原因=%d",gunid,pdata[5]);
				xx.result=1;
				xx.ctrlvalue=2;//pdata[5];

			}
		}
		else{
			g_can[gunid].state_ctrl = CTRL_PW_NORMAL;
			can_pro_debug1("收到功率调节，但是TCU未执行功率条件:gunid=%d  state_ctrl=%d ",gunid, g_can[gunid].state_ctrl );
			xx.result=1;
			xx.ctrlvalue=4;//pdata[5];

		}
		g_can[gunid].ms_fk_send = 0;
		g_can[gunid].ms_fk_recv = 0;
		myorder(gunid,(void*)&xx);

	}
	break;
	case CTL_CMD_ELE_LOCK_FEEDBACK:
		//		Set_UnsetOverTime(gunid,CTL_CMD_ELE_LOCK_FEEDBACK,0);
		//		clearOverTime(gunid,CTL_CMD_ELE_LOCK_FEEDBACK);
		can_pro_debug("解锁返回  %.*a",lendata, pdata);
		//		g_can[gunid].state_ctrl = CTRL_PW_NORMAL;
		//
		//		//		   g_can[gunid].state=TCU_READY;
		//		//		   g_can[gunid].curpf = 0;

		break;
		//	case CTL_CMD_AND_CHARGE_SETING_RESPONSE:
		//		if(g_can[gunid].state == TCU_CTRL_COMB)
		//		{
		//			if(pdata[2]==0 && pdata[1]==0x01)
		//			{
		//				can_pro_debug1("共充设置成功！！！！！");
		//				g_can[gunid].state=TCU_START_CHARGING;
		//				g_can[gunid].curpf = TCU_CMD_CHARGE_START;
		//				g_can[gunid].ctrltype=0;
		//			}
		//			else
		//			{
		//				can_pro_debug1("共充设置失败！！！！！");
		//				g_can[gunid].state=TCU_READY;
		//				g_can[gunid].curpf = 0;
		//				finStartCharge_f(gunid,0x45);
		//			}
		//		}
		//		else{
		//			can_pro_debug1("收到共充应答帧,但当前状态不是共充模式，curState:%d",g_can[gunid].state);
		//		}
		//		break;
		//
	default:
		break;

	}
	return ret;
}
int handleRecvPort(u8 port,u8 addr,msgtcu* pmsgs) {
	int ret;

	GW_Can *pmsg_rev=(GW_Can *)pmsgs->pmsg;


	if((gpcan_para->type == DC && pmsg_rev->pf==CTL_STATUS_STARTUP_COMPLETE)//gpcan_para->type == DC &&
			||(gpcan_para->type == DC && pmsg_rev->pf==CTL_STATUS_STOP_COMPLETE)//ltp change 2018-12-24 直流启动、停止完成帧为多帧
			|| pmsg_rev->pf==CTL_CMD_CHARGE_CONFIG_INFO_FEEDBACK
			|| pmsg_rev->pf==CTL_DATA_DC_TELEMETRY
			|| pmsg_rev->pf==CTL_DATA_AC_TELEMETRY
	)
	{
		u8 index;
		//pmsg_rev=(GW_Can *)pmsgs->pmsg;
		//    if(  pmsg_rev->pf==CTL_CMD_CHARGE_CONFIG_INFO_FEEDBACK)//   port==1 &&|| pmsg_rev->pf==CTL_STATUS_STOP_COMPLETE)pmsg_rev->pf==CTL_STATUS_STARTUP_COMPLETE  || CTL2TCU_NW_15 ||
		//		{
		////			g_can[0].ms_yc_recv =0;
		////			g_can[1].ms_yc_recv =0;
		//					can_pro_debug1("\r\n\r\n注意 注意：can多帧数据 port=%d  第%d包 pf=%x data=%.*a\r\n",port,pmsg_rev->pdata[0],pmsg_rev->pf,8,pmsg_rev->pdata);
		//			//	//	        printf("iii=%d\r\n\r\n",iii++);
		//		}

		ret=canCollectMultiFrameData(&index,port,addr,pmsg_rev->pf, pmsg_rev->pdata);
		if(ret==3)
		{
			memcpy(pmsg_rev->pdata,multFrame[index].multiFrameData,multFrame[index].dataLen + 3);	// 避免因拷贝总帧号，数据长度，遗漏数据
			pmsg_rev->lendata=multFrame[index].dataLen;
			if (msgsnd(sendpara[index].qid, pmsgs, sizeof(msgtcu), IPC_NOWAIT)
					!= -1)    //can_recv_form_tcu
			{
				if (pmsg_rev->pf == CTL_STATUS_STARTUP_COMPLETE ||pmsg_rev->pf == CTL_STATUS_STOP_COMPLETE ) {
					//					can_pro_debug1(
					//							"\r\n\r\n多帧数据发送到CANDLL port=%d addr=%x  data[]=%.*asucc succ succ succ !!!!!!!sendpara[multFrame->tcu_gunno].qid=%d multFrame->tcu_gunno=%d \r\n",
					//							port, addr, pmsg_rev->lendata, pmsg_rev->pdata,
					//							sendpara[multFrame->tcu_gunno].qid,
					//							multFrame->tcu_gunno);
					printf(
							"\n\n多帧数据发送到CANDLL port=%d addr=%x multFrame->tcu_gunno=%d  index=%d pf=%x\n",
							port, addr,
							multFrame->tcu_gunno,index,pmsg_rev->pf);

				}

			}
			else
			{
				//if(pmsg_rev->pf==CTL_STATUS_STOP_COMPLETE)
				can_pro_debug("\r\n\r\n多帧数据发送到CANDLL port=%d addr=%x  err err err err !!!!!!!\r\n",port,addr);
				//		    	while(1)
				//		    	{
				//		    		printf("发送失败！！");
				//		    	}
			}

			multFrame[index].dataIndex = 0;
			multFrame[index].frameIndex = 0;
			multFrame[index].frameSumCount = 0;
			multFrame[index].dataLen = 0;
			multFrame[index].lastFrameDataLen = 0;
			multFrame[index].priPF = 0;
			memset(&multFrame[index].multiFrameData[0],0,128);

			//	ret=AnalyzeData(port,gunid1,pmsg_rev->pf,multFrame[gunid].dataIndex,multFrame[gunid].multiFrameData);
		}
	}
	else if((gpcan_para->type == AC && pmsg_rev->pf==CTL_STATUS_STARTUP_COMPLETE)
			||(gpcan_para->type == AC && pmsg_rev->pf==CTL_STATUS_STOP_COMPLETE)//ltp change 2018-12-24 交流启动、停止完成帧为单帧
			||pmsg_rev->pf==CTL_ERROR_STATUS
			||pmsg_rev->pf==CTL_DATA_DC_TELESIGNAL_1
			||pmsg_rev->pf==CTL_DATA_DC_TELESIGNAL_2
			||pmsg_rev->pf==CTL_DATA_AC_TELESIGNAL_1
			||pmsg_rev->pf==CHA_HEART
			||pmsg_rev->pf==CTL_CMD_VERSION_CONFIRM
			||pmsg_rev->pf==CTL_CMD_TIME_SET
			||pmsg_rev->pf==CTL_CMD_START_RESPONSE
			||pmsg_rev->pf==CTL_CMD_STOP_RESPONSE
			||pmsg_rev->pf==CTL_CMD_CHARGE_PARAM_CONFIRM
			||pmsg_rev->pf==CTL_CMD_POWER_ADJUST_FEEDBACK
			||pmsg_rev->pf==CTL_CMD_ELE_LOCK_FEEDBACK
			||pmsg_rev->pf==CTL_CMD_AND_CHARGE_SETING_RESPONSE
			||pmsg_rev->pf==CTL2TCU_XJ_DC_15
			||pmsg_rev->pf==CTL2TCU_XJ_AC_16

	)

	{
		u8 gunid_cha=pmsg_rev->pdata[0];
		int gunid_tcu1;
		u8 gunid_tcu;
		gunid_tcu1=countGunno1( port,addr,gunid_cha);

		if(gunid_tcu1==-1)
		{
			can_pro_debug1("000收到错误的单帧数据 port=%d,addr=%x,gunid_cha=%x 帧=%x %x %x",port,addr,gunid_cha,pmsg_rev->pdata[0],pmsg_rev->pdata[1],pmsg_rev->pdata[2]);
			if(pmsg_rev->pdata!=NULL)
				can_pro_debug1("收到错误的单帧数据 port=%d,addr=%x,gunid_cha=%x 帧=%.*a",port,addr,gunid_cha,4,pmsg_rev->pdata);
			else
				can_pro_debug1("收到错误的单帧数据 port=%d,addr=%x,gunid_cha=%x 帧",port,addr,gunid_cha);

			return -1;
		}
		else
			gunid_tcu=gunid_tcu1;
		if(pmsg_rev->pf==CTL_CMD_START_RESPONSE)
		{
			//			sprintf(_tmp_print_str,"收到启动返回应答   gunid=%d  01返回02\r\n",gunid_tcu);
			//			gpcan_para->writelog(_tmp_print_str);
		}
		//	if(port==0 && pmsg_rev->pf==CTL_DATA_DC_TELESIGNAL_1)
		//	if(pmsg_rev->pf==CHA_HEART)
		//		    can_pro_debug("心跳 心跳  单帧数据  tcuid=%d   port=%d  addr=%x pf=%x   ",gunid_tcu,port,addr,pmsg_rev->pf);
		//	else
		//		  can_pro_debug("单帧数据  tcuid=%d   port=%d  addr=%x pf=%x   ",gunid_tcu,port,addr,pmsg_rev->pf);
		if(msgsnd(sendpara[gunid_tcu].qid, pmsgs, sizeof(msgtcu), IPC_NOWAIT) != -1)//can_recv_form_tcu
		{
			//		    	if(gwcan.pf ==0x61)
			//		   if(port==0 && pmsg_rev->pf==CTL_DATA_DC_TELESIGNAL_1)
			//        can_pro_debug1("\r\n\r\n单帧数据发送到CANDLL port=%d addr=%x  succ succ succ  !!!!!!!  sendpara[%d].qid=%d\r\n",port,addr,gunid_tcu,sendpara[gunid_tcu].qid);
		}
		else
		{
			//     if(port==0 && pmsg_rev->pf==CTL_DATA_DC_TELESIGNAL_1)
			can_pro_debug("\r\n\r\n单帧数据发送到CANDLL port=%d addr=%x  err err err err !!!!!!!\r\n",port,addr);
			//  	sleep(2);
		}

	}

	else
	{
		printf("注意 注意：未编程的pf=%x",pmsg_rev->pf);
		return -1;
	}
	return ret;
}
int canSendHeartFrame(u8 gunid) {//心跳
	static u8 count[]={0,0,0,0,0,0,0,0};
	GW_Can gwsend;

	count[gunid]++;
	gwsend.pf=cha2tcu_tab[g_can[gunid].heart_pos].pf;
	gwsend.sa=gpcan_para->pgun_info[gunid].tcu_addr;
	gwsend.ps=gpcan_para->pgun_info[gunid].cha_addr;
	gwsend.priority=cha2tcu_tab[g_can[gunid].heart_pos].priority;
	gwsend.lendata=8;

	can_pro_debug("向控制器发送心跳包  pf=%x   g_can[%d].state=%d gunid=%d ",gwsend.pf,gunid,g_can[gunid].state,gunid);
	memset(gwsend.pdata, 0, gwsend.lendata);
	gwsend.pdata[0]=gpcan_para->pgun_info[gunid].frm_gunno;//枪号

	gwsend.pdata[1] = count[gunid];
	can_pro_debug("000向控制器发送心跳包  pf=%x   g_can[%d].state=%d  frame=%.*a",gwsend.pf,gunid,g_can[gunid].state,gwsend.lendata,gwsend.pdata);
	if(g_can[gunid].ms_heart_recv>=cha2tcu_tab[g_can[gunid].heart_pos].over)
		gwsend.pdata[2]=0;

	sendFrameToMain(gpcan_para->pgun_info[gunid].port,&gwsend);

	g_can[gunid].ms_heart_send=0;
	return 0;
}
int SendErr2Cha(u8 gunid, u16 errCode) {

	GW_Can gwsend;

	can_pro_debug("[ 错误帧 ]向控制器%d发送错误代码: %x",gunid,errCode);
	gwsend.pf=cha2tcu_tab[g_can[gunid].err_pos].pf;
	gwsend.sa=gpcan_para->pgun_info[gunid].tcu_addr;
	gwsend.ps=gpcan_para->pgun_info[gunid].cha_addr;
	gwsend.priority=cha2tcu_tab[g_can[gunid].heart_pos].priority;
	memset(gwsend.pdata,0,8);
	gwsend.lendata=8;
	gwsend.pdata[0]=gpcan_para->pgun_info[gunid].frm_gunno;//枪号

	gwsend.pdata[1]=errCode%256;
	gwsend.pdata[2]=errCode/256;//
	sendFrameToMain(gpcan_para->pgun_info[gunid].port,&gwsend);
	g_can[gunid].ms_err_send=0;
	return 0;
}
//发送遥测
int SendYc_pf21(u8 gunid) {
	GW_Can gwsend;

	//	int i=0;
	gwsend.pf=cha2tcu_tab[g_can[gunid].yc_pos].pf;
	gwsend.sa=gpcan_para->pgun_info[gunid].tcu_addr;
	gwsend.ps=gpcan_para->pgun_info[gunid].cha_addr;
	gwsend.priority=cha2tcu_tab[g_can[gunid].heart_pos].priority;

	memset(gwsend.pdata,0,17);
	can_pro_debug("定时发送遥测命令pf=%x！！！",gwsend.pf);
	gwsend.pdata[0]=gpcan_para->pgun_info[gunid].frm_gunno;//枪号

	if (gpcan_para->type == DC && fac31==0) {
		//			candll_debug("向控制器发送遥测  电量=%d  时间=%d",gpcan_para->data2main->gun[gunid].yc_in_data.dc.MX[0],
		//					gpcan_para->data2main->gun[gunid].yc_in_MidSplitTableSearchdata.dc.MX[1]);
		gwsend.pdata[1] =  gpcan_para->data2main->gun[gunid].yc_in_data.MX[6]%256; //当前充电电量
		gwsend.pdata[2] =  gpcan_para->data2main->gun[gunid].yc_in_data.MX[6]/256; //当前充电电量
		gwsend.pdata[3] =  gpcan_para->data2main->gun[gunid].yc_in_data.MX[7]%256; //累计充电时长
		gwsend.pdata[4] =  gpcan_para->data2main->gun[gunid].yc_in_data.MX[7]/256; //累计充电时长
		//ltp change 2018-12-26
		if(g_can[gunid].state != WAIT_CHARGEING2){
			gwsend.pdata[1] = 0;
			gwsend.pdata[2] = 0;
			gwsend.pdata[3] = 0;
			gwsend.pdata[4] = 0;
		}
		gwsend.lendata=8;
	} else// if (gpcan_para->type == AC)
	{
		can_pro_debug("向控制器发送遥测  A电压=%d  A电流=%d",gpcan_para->data2main->gun[gunid].yc_in_data.MX[0],
				gpcan_para->data2main->gun[gunid].yc_in_data.MX[3]);
		can_pro_debug("向控制器发送遥测  B电压=%d  B电流=%d",gpcan_para->data2main->gun[gunid].yc_in_data.MX[1],
				gpcan_para->data2main->gun[gunid].yc_in_data.MX[4]);
		can_pro_debug("向控制器发送遥测  C电压=%d  C电流=%d",gpcan_para->data2main->gun[gunid].yc_in_data.MX[2],
				gpcan_para->data2main->gun[gunid].yc_in_data.MX[5]);
		can_pro_debug("向控制器发送遥测  电量=%d  充电时间=%d",gpcan_para->data2main->gun[gunid].yc_in_data.MX[6],
				gpcan_para->data2main->gun[gunid].yc_in_data.MX[7]);
		gwsend.pdata[1] =    gpcan_para->data2main->gun[gunid].yc_in_data.MX[0]%256;//A相充电电压
		gwsend.pdata[2] =    gpcan_para->data2main->gun[gunid].yc_in_data.MX[0]/256;//A相充电电压
		gwsend.pdata[3] =    gpcan_para->data2main->gun[gunid].yc_in_data.MX[1]%256;//B相充电电压
		gwsend.pdata[4] =    gpcan_para->data2main->gun[gunid].yc_in_data.MX[1]/256;//B相充电电压
		gwsend.pdata[5] =    gpcan_para->data2main->gun[gunid].yc_in_data.MX[2]%256;//C相充电电压
		gwsend.pdata[6] =    gpcan_para->data2main->gun[gunid].yc_in_data.MX[2]/256;//C相充电电压
		gwsend.pdata[7] =    gpcan_para->data2main->gun[gunid].yc_in_data.MX[3]%256;//A相充电电流
		gwsend.pdata[8] =    gpcan_para->data2main->gun[gunid].yc_in_data.MX[3]/256;//A相充电电流
		gwsend.pdata[9] =    gpcan_para->data2main->gun[gunid].yc_in_data.MX[4]%256;//B相充电电流
		gwsend.pdata[10] =  gpcan_para->data2main->gun[gunid].yc_in_data.MX[4]/256;//B相充电电流
		gwsend.pdata[11] =  gpcan_para->data2main->gun[gunid].yc_in_data.MX[5]%256; ;//C相充电电流
		gwsend.pdata[12] =  gpcan_para->data2main->gun[gunid].yc_in_data.MX[5]/256; ;//C相充电电流
		gwsend.pdata[13] =  gpcan_para->data2main->gun[gunid].yc_in_data.MX[6]%256; //当前充电电量
		gwsend.pdata[14] =  gpcan_para->data2main->gun[gunid].yc_in_data.MX[6]/256; //当前充电电量
		gwsend.pdata[15] =  gpcan_para->data2main->gun[gunid].yc_in_data.MX[7]%256; //累计充电时长
		gwsend.pdata[16] =  gpcan_para->data2main->gun[gunid].yc_in_data.MX[7]/256; //累计充电时长

		//ltp change 2018-12-26
		if(g_can[gunid].state != WAIT_CHARGEING2){
			gwsend.pdata[13] = 0;
			gwsend.pdata[14] = 0;
			gwsend.pdata[15] = 0;
			gwsend.pdata[16] = 0;
		}

		gwsend.lendata=17;
		can_pro_debug("向控制器发送遥测pf=%x  %.*a",gwsend.pf,17,gwsend.pdata);
	}
	sendFrameToMain(gpcan_para->pgun_info[gunid].port,&gwsend);
	g_can[gunid].ms_yc_send=0;
	return 0;
}

int  FinStartStopBack(u8 gunid,u8 pf)
{
	GW_Can gwsend;
	if(g_can[gunid].curpf!=pf)
	{
		g_can[gunid].curpf=pf;
		g_can[gunid].curpos = TableSearch(g_can[gunid].curpf, (u8*) cha2tcu_tab,
				sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);

	}


	memset(&gwsend,0,sizeof(gwsend));
	gwsend.pf=cha2tcu_tab[g_can[gunid].curpos].pf;
	gwsend.sa=gpcan_para->pgun_info[gunid].tcu_addr;
	gwsend.ps=gpcan_para->pgun_info[gunid].cha_addr;
	gwsend.priority=cha2tcu_tab[g_can[gunid].curpos].priority;
	printf("发送pf=%x  FinStartStopBack gwsend.pf=%x\r\n ",pf,gwsend.pf);
	gwsend.lendata=8;
	gwsend.pdata[0]=gpcan_para->pgun_info[gunid].frm_gunno;//枪号

	if(pf==TCU_STATUS_STARTUP_COMPLETE_RESPONSE)
	{
		gwsend.pdata[1] =g_u3[gunid].MX1;
		gwsend.pdata[2] = g_u3[gunid].MX2;
	}
	else if(pf==TCU_STATUS_STOP_COMPLETE_RESPONSE)
	{
		gwsend.pdata[1] =g_u4[gunid].MX2;

	}
	sendFrameToMain(gpcan_para->pgun_info[gunid].port,&gwsend);
	g_can[gunid].ms_cur_send = 0;
	return 0;

}
int off_gunLock(u8 gunid,u8 type) {
	GW_Can gwsend;
	u16 pos;//正在执行的pf在表格中的位置
	can_pro_debug("1111[STOP]收到电子锁解锁指令，向控制器发送");
	pos = TableSearch(TCU_CMD_ELE_LOCK_CONTROL, (u8*) cha2tcu_tab,sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);
	memset(&gwsend,0,sizeof(gwsend));
	gwsend.pf=TCU_CMD_ELE_LOCK_CONTROL;//cha2tcu_tab[g_can[gunid].curpos].pf;
	gwsend.sa=gpcan_para->pgun_info[gunid].tcu_addr;
	gwsend.ps=gpcan_para->pgun_info[gunid].cha_addr;
	gwsend.priority=cha2tcu_tab[pos].priority;

	gwsend.lendata=8;
	gwsend.pdata[0]=gpcan_para->pgun_info[gunid].frm_gunno;//枪号
	gwsend.pdata[1]=1;//
	gwsend.pdata[2]=type;//
	sendFrameToMain( gpcan_para->pgun_info[gunid].port,&gwsend);
	g_can[gunid].ms_fk_send=0;
	printf("解锁包  pf=%02x priority:%02x [ ",gwsend.pf, gwsend.priority);
	for(int i=0; i<gwsend.lendata;i++)
		printf("%02x ",gwsend.pdata[i]);
	printf("]\n");

	return 0;

}
/*
停止充电函数，gunid 充电接口标识, ret 1--启用功率调节，2--关闭功率调节。收到充电结束返回
 返回：0 - 成功, 1 - 失败
 */
int stop_charge(u8 gunid, char reason) {

	GW_Can gwsend;
	if(g_can[gunid].curpf!=TCU_CMD_CHARGE_STOP)
	{
		can_pro_debug("1111[STOP]收到停止充电指令，向控制器发送停止充电");
		g_can[gunid].curpf=TCU_CMD_CHARGE_STOP;
		g_can[gunid].curpos = TableSearch(g_can[gunid].curpf, (u8*) cha2tcu_tab,
				sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);
		// return 1;
	}
	can_pro_debug("2222[STOP]收到停止充电指令，向控制器发送停止充电");
	memset(&gwsend,0,sizeof(gwsend));
	gwsend.pf=cha2tcu_tab[g_can[gunid].curpos].pf;
	gwsend.sa=gpcan_para->pgun_info[gunid].tcu_addr;
	gwsend.ps=gpcan_para->pgun_info[gunid].cha_addr;
	gwsend.priority=cha2tcu_tab[g_can[gunid].curpos].priority;

	gwsend.lendata=8;
	gwsend.pdata[0]=gpcan_para->pgun_info[gunid].frm_gunno;//枪号

	gwsend.pdata[1]= reason&0x03;//
	sendFrameToMain( gpcan_para->pgun_info[gunid].port,&gwsend);
	g_can[gunid].ms_cur_send = 0;
	can_pro_debug("向控制器停止充电指令gwsend.pf= %x 数据=%.*a",gwsend.pf,8,gwsend.pdata);

	return 0;
}
int start_charge_comb( u8 gunid) {
	GW_Can gwsend;
	//	u16 value=100;//100.0%;
	u8 i;
	can_pro_debug("向控制器发送共充充电指令cha2tcu_tab[g_can[gunid].curpos].pf=%x  curState=%x  gunid=%d！！！！",cha2tcu_tab[g_can[gunid].curpos].pf,TCU_CTRL_COMB,gunid);
	if(g_can[gunid].curpf!=TCU_CMD_AND_CHARGE_SETING)
	{
		g_can[gunid].curpf=TCU_CMD_AND_CHARGE_SETING;
		g_can[gunid].curpos = TableSearch(g_can[gunid].curpf, (u8*) cha2tcu_tab,
				sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);

	}
	memset(&gwsend,0,sizeof(gwsend));
	gwsend.pf=cha2tcu_tab[g_can[gunid].curpos].pf;
	gwsend.sa=gpcan_para->pgun_info[gunid].tcu_addr;
	gwsend.ps=gpcan_para->pgun_info[gunid].cha_addr;
	gwsend.priority=cha2tcu_tab[g_can[gunid].curpos].priority;

	gwsend.lendata=8;
	gwsend.pdata[0]=gpcan_para->pgun_info[gunid].frm_gunno;//枪号
	gwsend.pdata[1] = 0x01;
	sendFrameToMain( gpcan_para->pgun_info[gunid].port,&gwsend);
	g_can[gunid].ms_cur_send = 0;
	printf("pf=%02x priority:%02x [ ",gwsend.pf, gwsend.priority);
	for(i=0; i<gwsend.lendata;i++)
		printf("%02x ",gwsend.pdata[i]);
	printf("]\n");

	return 0;
}

/*
 启动充电函数，gunid 充电接口标识, ctrlPW 1--启用功率调节，2--关闭功率调节。
 返回：0 - 成功, 1 - 失败
 */
int start_charge(u8 gunid, char ctrlPW) {//

	GW_Can gwsend;
	can_pro_debug("准备充电,第 %d号枪当前状态 state=%d  pf=%x ",gunid,g_can[gunid].state,g_can[gunid].curpf);
	if(g_can[gunid].curpf != TCU_CMD_CHARGE_START)
	{
		g_can[gunid].curpf=TCU_CMD_CHARGE_START;
		g_can[gunid].curpos = TableSearch(g_can[gunid].curpf, (u8*) cha2tcu_tab,
				sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);
		// return 1;
	}
	memset(&gwsend,0,sizeof(gwsend));
	gwsend.pf=cha2tcu_tab[g_can[gunid].curpos].pf;
	gwsend.sa=gpcan_para->pgun_info[gunid].tcu_addr;
	gwsend.ps=gpcan_para->pgun_info[gunid].cha_addr;
	gwsend.priority=cha2tcu_tab[g_can[gunid].curpos].priority;

#ifdef  CCU_VERSION_V2_3
	gwsend.lendata=8;
	gwsend.pdata[0]=gpcan_para->pgun_info[gunid].frm_gunno;	//枪号
	gwsend.pdata[1]=ctrlPW;									//负荷控制开关
	gwsend.pdata[2]=0;										//0:非即插即充，1：即插即充
#else
	gwsend.lendata=8; 
	gwsend.pdata[0]=gpcan_para->pgun_info[gunid].frm_gunno;//枪号
	gwsend.pdata[1]=ctrlPW;									//负荷控制开关
	gwsend.pdata[2]=0;
#endif
	sendFrameToMain( gpcan_para->pgun_info[gunid].port,&gwsend);
	g_can[gunid].ms_cur_send = 0;
	return 0;

}
int adjust_pw(u8 gunid)
{

	GW_Can gwsend;
	u8 pf;
	u16 pos;
	can_pro_debug1(" adjust_pw第 %d号枪当前状态 state=%d  pf=%x ",gunid,g_can[gunid].state,g_can[gunid].curpf);
	pf=TCU_CMD_POWER_ADJUST_CONTROL;
	pos = TableSearch(pf, (u8*) cha2tcu_tab,
			sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);

	memset(&gwsend,0,sizeof(gwsend));
	gwsend.pf=pf;
	gwsend.sa=gpcan_para->pgun_info[gunid].tcu_addr;
	gwsend.ps=gpcan_para->pgun_info[gunid].cha_addr;
	gwsend.priority=cha2tcu_tab[pos].priority;

	gwsend.lendata=8;
	gwsend.pdata[0]=gpcan_para->pgun_info[gunid].frm_gunno;//枪号

	gwsend.pdata[1] = g_can[gunid].ctrltype;
	if(g_can[gunid].ctrltype==1 || g_can[gunid].ctrltype==2){
		gwsend.pdata[2] = (u8)g_can[gunid].ctrlvalue;
		gwsend.pdata[3] = (u8)(g_can[gunid].ctrlvalue>>8);
		gwsend.pdata[4] = (u8)g_can[gunid].ctrtime;
		gwsend.pdata[5] = (u8)(g_can[gunid].ctrtime>>8);
	}

	sendFrameToMain( gpcan_para->pgun_info[gunid].port,&gwsend);
	g_can[gunid].ms_cur_send = 0;
	return 0;

}

//int adjust_pw(u8 gunid)
//{
//
//	GW_Can gwsend;
//	can_pro_debug("第 %d号枪当前状态 state=%d  pf=%x ",gunid,g_can[gunid].state,g_can[gunid].curpf);
//	if(g_can[gunid].curpf!=TCU_CMD_POWER_ADJUST_CONTROL)
//	{
//	      g_can[gunid].curpf=TCU_CMD_POWER_ADJUST_CONTROL;
//	      g_can[gunid].curpos = TableSearch(g_can[gunid].curpf, (u8*) cha2tcu_tab,
//			sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);
//	      return 1;
//
//	}
//
//	memset(&gwsend,0,sizeof(gwsend));
//	gwsend.pf=cha2tcu_tab[g_can[gunid].curpos].pf;
//	gwsend.sa=gpcan_para->pgun_info[gunid].tcu_addr;
//	gwsend.ps=gpcan_para->pgun_info[gunid].cha_addr;
//	gwsend.priority=cha2tcu_tab[g_can[gunid].curpos].priority;
//
//	gwsend.lendata=8;
//	gwsend.pdata[0]=gpcan_para->pgun_info[gunid].frm_gunno;//枪号
//
//	gwsend.pdata[1] = g_can[gunid].ctrltype;
//	gwsend.pdata[2] = (u8)g_can[gunid].ctrlvalue;
//	gwsend.pdata[3] = (u8)(g_can[gunid].ctrlvalue>>8);
//
//	sendFrameToMain( gpcan_para->pgun_info[gunid].port,&gwsend);
//    g_can[gunid].ms_cur_send = 0;
//	return 0;
//
//}
//对时

int setChaTime( u8 gunid)
{
	TDateTime datetime;
	GW_Can gwsend;
	can_pro_debug("第三步：发送对时命令！！！gunid=%d",gunid);
	read_current_datetime(&datetime);


	if(g_can[gunid].curpf!=TCU_CMD_TIME_SET)
	{
		g_can[gunid].curpf=TCU_CMD_TIME_SET;
		g_can[gunid].curpos = TableSearch(g_can[gunid].curpf, (u8*) cha2tcu_tab,
				sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);
	}

	memset(&gwsend,0,sizeof(gwsend));
	gwsend.pf=cha2tcu_tab[g_can[gunid].curpos].pf;
	gwsend.sa=gpcan_para->pgun_info[gunid].tcu_addr;
	gwsend.ps=gpcan_para->pgun_info[gunid].cha_addr;
	gwsend.priority=cha2tcu_tab[g_can[gunid].curpos].priority;





	gwsend.lendata=8;
	gwsend.pdata[0]=gpcan_para->pgun_info[gunid].frm_gunno;//枪号

	g_can[gunid].ms_cur_send = 0;
	gwsend.pdata[1] =datetime.Msec%256;
	gwsend.pdata[2] =datetime.Msec/256;

	gwsend.pdata[3] =datetime.Min;
	gwsend.pdata[4] =datetime.Hour;

	gwsend.pdata[5] =datetime.Day;
	gwsend.pdata[6] =datetime.Month;
	gwsend.pdata[7] =datetime.Year;

	can_pro_debug("第三步：发送对时命令  pf=%x",gwsend.pf);
	sendFrameToMain( gpcan_para->pgun_info[gunid].port,&gwsend);
	g_can[gunid].ms_cur_send = 0;
	return 0;
}
int configPara(u8 gunid) {

	GW_Can gwsend;
	if(g_can[gunid].curpf!=TCU_CMD_CHARGE_CONFIG_INFO_QUERY)
	{
		g_can[gunid].curpf=TCU_CMD_CHARGE_CONFIG_INFO_QUERY;
		g_can[gunid].curpos = TableSearch(g_can[gunid].curpf, (u8*) cha2tcu_tab,
				sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);

	}
	memset(&gwsend,0,sizeof(gwsend));
	gwsend.pf=cha2tcu_tab[g_can[gunid].curpos].pf;
	gwsend.sa=gpcan_para->pgun_info[gunid].tcu_addr;
	gwsend.ps=gpcan_para->pgun_info[gunid].cha_addr;
	gwsend.priority=cha2tcu_tab[g_can[gunid].curpos].priority;

	gwsend.lendata=8;

	can_pro_debug("第四步：发送配置参数查询  pf=%x gunid=%d",gwsend.pf,gunid);
	gwsend.pdata[0]=gpcan_para->pgun_info[gunid].frm_gunno;//枪号
	sendFrameToMain( gpcan_para->pgun_info[gunid].port,&gwsend);
	g_can[gunid].ms_cur_send = 0;
	return 0;
}

int sendChargePara(u8 gunid)
{
	GW_Can gwsend;
	if(g_can[gunid].curpf!=TCU_CMD_SEND_CHARGE_PARAM)
	{
		g_can[gunid].curpf=TCU_CMD_SEND_CHARGE_PARAM;
		g_can[gunid].curpos = TableSearch(g_can[gunid].curpf, (u8*) cha2tcu_tab,
				sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);

	}
	memset(&gwsend,0,sizeof(gwsend));
	gwsend.pf=cha2tcu_tab[g_can[gunid].curpos].pf;
	gwsend.sa=gpcan_para->pgun_info[gunid].tcu_addr;
	gwsend.ps=gpcan_para->pgun_info[gunid].cha_addr;
	gwsend.priority=cha2tcu_tab[g_can[gunid].curpos].priority;
	gwsend.lendata=8;

	can_pro_debug("第二步：发送充电参数 gwsend.pf=%x gunid=%d",gwsend.pf,gunid);
	gwsend.pdata[0]=gpcan_para->pgun_info[gunid].frm_gunno;//枪号
	memcpy(&gwsend.pdata[1],gpcan_para->devNo,7);
	sendFrameToMain( gpcan_para->pgun_info[gunid].port,&gwsend);
	g_can[gunid].ms_cur_send = 0;
	return 0;
}

int checkver(u8 gunid)
{
	GW_Can gwsend;

	if(g_can[gunid].curpf!=TCU_CMD_VERSION_CALIBRATION)
	{
		g_can[gunid].curpf=TCU_CMD_VERSION_CALIBRATION;
		g_can[gunid].curpos = TableSearch(g_can[gunid].curpf, (u8*) cha2tcu_tab,
				sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);

	}

	//	can_pro_debug1("第一步：发送版本校验 g_can[gunid].curpos=%d",g_can[gunid].curpos);
	memset(&gwsend,0,sizeof(gwsend));
	gwsend.pf=cha2tcu_tab[3].pf;//g_can[gunid].curpos
	gwsend.sa=gpcan_para->pgun_info[gunid].tcu_addr;
	gwsend.ps=gpcan_para->pgun_info[gunid].cha_addr;
	gwsend.priority=cha2tcu_tab[g_can[gunid].curpos].priority;

	gwsend.lendata=8;
	can_pro_debug1("第一步：发送版本校验 pf=%x gunid=%d",gwsend.pf,gunid);
	//	sprintf(_tmp_print_str,"第一步：发送版本校验 pf=%x gunid=%d",gwsend.pf,gunid);
	//	gpcan_para->writelog(_tmp_print_str);
	gwsend.pdata[0]=gpcan_para->pgun_info[gunid].frm_gunno;//枪号
	gwsend.pdata[1] = gpcan_para->can_ver[0];
	gwsend.pdata[2] = gpcan_para->can_ver[1];

	sendFrameToMain( gpcan_para->pgun_info[gunid].port,&gwsend);

	g_can[gunid].ms_cur_send = 0;
	return 0;
}
int gotoCHECK_VER(u8 gunid,u8 pf,u8 flag)//返回匹配开始
{
	if (Set_UnsetOverTime(gunid, pf) == 1) {
		if (flag == 1) {

			g_can[gunid].state = CHECK_VER; //返回匹配开始
			//checkver(gunid);
			g_can[gunid].ms_cur_recv = 0;
		}

	}
	else
	{
		printf("\r\n没找到需要超时的  pf=%x\r\n",pf);
	}
	return 0;
}
void auto2Cha(u8 gunid) {
	if ((g_can[gunid].ms_cur_send < cha2tcu_tab[g_can[gunid].curpos].dly)  &&  (g_can[gunid].state != WAIT_CHARGE)) {

		return;
	}
	switch (g_can[gunid].state) {
	case CHECK_VER:
		printf("发送版本校验CHECK_VER gunid=%d  g_can[gunid].err_code_all=%d\r\n", gunid,g_can[gunid].err_code_all);
		if(g_can[gunid].err_code_all!=0)//等待错误帧发送完毕
		{
			printf("等待错误帧发送完毕 等待错误帧发送完毕 等待错误帧发送完毕  g_can[gunid].err_code_all=%d\r\n",g_can[gunid].err_code_all);
			break;
		}
		//		if (g_can[gunid].ms_cur_recv
		//				>= cha2tcu_tab[g_can[gunid].curpos].over * 1000 ) {
		//		   if (gpcan_para->firm_id== GW_SDANDARD) {//直接进入下一步
		//
		//				g_can[gunid].state = SEND_CHARGE_PARAM;
		//				g_can[gunid].ms_cur_recv = 0;
		//				sendChargePara(gunid);
		//			}
		//		} else
		checkver(gunid);

		break;
	case	SEND_CHARGE_PARAM:
		if (g_can[gunid].ms_cur_recv
				>= cha2tcu_tab[g_can[gunid].curpos].over * 1000) {
			if (gpcan_para->firm_id == GW_SDANDARD) {
				printf("下发充电参数应答超时\r\n");
				//				sprintf(_tmp_print_str,"下发充电参数应答超时\r\n");
				//				gpcan_para->writelog(_tmp_print_str);
				//		    	gotoCHECK_VER(gunid,g_can[gunid].curpf,1);//下发充电参数应答超时（发送pf=09等待pf=0a超时 返回匹配开始阶段）
			}
			else
			{ //直接进入下一步

				g_can[gunid].state = TCU_SET_TIME;
				g_can[gunid].ms_cur_recv = 0;
				setChaTime (gunid);
			}
		} else
			sendChargePara(gunid);

		break;
	case  TCU_SET_TIME:
		if (g_can[gunid].ms_cur_recv
				>= cha2tcu_tab[g_can[gunid].curpos].over * 1000) {
			//			if (gpcan_para->firm_id == GW_SDANDARD) {
			printf("设置控制器时间超时,直接进入下一步  \r\n");
			printf("设置控制器时间未接收确认时间 g_can[gunid].ms_cur_recv=%d",g_can[gunid].ms_cur_recv);
			//				sprintf(_tmp_print_str,"设置控制器时间未接收确认时间 g_can[gunid].ms_cur_recv=%d\n",g_can[gunid].ms_cur_recv);
			//				gpcan_para->writelog(_tmp_print_str);
			//
			//		    	gotoCHECK_VER(gunid,g_can[gunid].curpf,0);//下发充电参数应答超时（发送pf=09等待pf=0a超时 返回匹配开始阶段）
			//
			//
			//			}
			//		else
			{ //直接进入下一步

				g_can[gunid].state = CONFIG_INFO_QUERY;
				g_can[gunid].ms_cur_recv = 0;
				configPara (gunid);
			}
		} else
		{
			printf("设置控制器时间未接收确认时间 g_can[gunid].ms_cur_recv=%d 但重发时间到",g_can[gunid].ms_cur_recv);
			setChaTime(gunid);
		}

		break;
	case 	CONFIG_INFO_QUERY:
		if (g_can[gunid].ms_cur_recv
				>= cha2tcu_tab[g_can[gunid].curpos].over * 1000) {
			if (gpcan_para->firm_id == GW_SDANDARD) {
				printf("配置参数查询应答超时\r\n");

				//				sprintf(_tmp_print_str,"配置参数查询应答超时\r\n");
				//				gpcan_para->writelog(_tmp_print_str);
				//	gotoCHECK_VER(gunid,g_can[gunid].curpf,1);//配置参数查询应答超时（发送pf=60等待pf=61超时 返回匹配开始阶段）
			}
			else
			{ //直接进入下一步
				g_can[gunid].ms_yc_recv =0;
				g_can[gunid].ms_yx_recv=0;
				g_can[gunid].err_code_all =0;
				g_can[gunid].state = TCU_READY;
				g_can[gunid].curpf = 0;
				g_can[gunid].ms_cur_send = 0;
				g_can[gunid].ms_cur_recv = 0;
			}
		} else
			configPara(gunid);
		break;
	case    TCU_CTRL_COMB:
		printf("444222333444\r\n");
		if (g_can[gunid].ms_cur_recv
				>= cha2tcu_tab[g_can[gunid].curpos].over * 1000) {
			g_can[gunid].state = TCU_START_CHARGING;
			start_charge(gunid, 2);
			g_can[gunid].ms_cur_recv = 0;
		} else
			start_charge_comb(gunid);
		break;

	case    TCU_START_CHARGING:
		printf("444222333444\r\n");
		if(g_can[gunid].curpf !=TCU_CMD_CHARGE_START)
			printf("\r\n\r\n注意：命令出错了  g_can[gunid].curpf =%x  正确是：%x\r\n\r\n",g_can[gunid].curpf ,TCU_CMD_CHARGE_START);

		if (g_can[gunid].ms_cur_recv
				>= cha2tcu_tab[g_can[gunid].curpos].over * 1000) {//发送充电应答超时（发送pf=01等待pf=02超时 返回充电待机）

			finStartCharge_f(gunid, OVER_TIME_PF01);	//发送01后未能返回02（超时）

			if (gpcan_para->firm_id == GW_SDANDARD) {
				//		gotoCHECK_VER(gunid, g_can[gunid].curpf, 0);
				g_can[gunid].state = TCU_READY;
				g_can[gunid].curpf = 0;
				g_can[gunid].ms_cur_send = 0;
				g_can[gunid].ms_cur_recv = 0;
			} else {

				g_can[gunid].state = TCU_READY;
				g_can[gunid].curpf = 0;
				g_can[gunid].ms_cur_send = 0;
				g_can[gunid].ms_cur_recv = 0;
			}
			g_can[gunid].ctrltype = 0;

		}
		else
			start_charge(gunid, 2);//重复发送01等待02
		break;

	case    WAIT_CHARGE:
		//	printf("WAIT_CHARGE  控制器返回02后等待启动完成帧pf=0x11过程 g_can[gunid].ms_cur_recv=%d\r\n",g_can[gunid].ms_cur_recv);

		if(g_can[gunid].ms_cur_recv
				>= FIN_START_CHARGE * 1000)//等待控制器充电完成超时（等待pf=11超时）
		{
			//	gotoCHECK_VER(gunid,g_can[gunid].curpf,0);
			//			if (getChargeState(gunid) == 1) {//虽然未收到启动完成，但控制器已经充电，因此进入停止充电
			//				g_can[gunid].state = TCU_STOP_CHARGING;
			//				g_can[gunid].stop_reason=1;
			//				stop_charge(gunid,g_can[gunid].stop_reason);
			//
			//			} else {
			//				finStartCharge_f(gunid,OVER_TIME_PE11);
			//				g_can[gunid].state = TCU_READY;
			//				g_can[gunid].ms_cur_send = 0;
			//			}

			finStartCharge_f(gunid, OVER_TIME_PE11);
			g_can[gunid].state = TCU_READY;
			g_can[gunid].ms_cur_send = 0;
			g_can[gunid].ms_cur_recv = 0;
			g_can[gunid].ctrltype = 0;
		}
		break;
	case    WAIT_CHARGEING1:
		//printf("WAIT_CHARGEING1 收到11 重复发送12,大约5s  g_can[gunid].ms_cur_recv=%d\r\n",g_can[gunid].ms_cur_recv);//but break, don't change state, curState
		if(g_can[gunid].curpf !=TCU_STATUS_STARTUP_COMPLETE_RESPONSE)
			printf("\r\n\r\n注意：命令出错了  g_can[gunid].curpf =%x  正确是：%x\r\n\r\n",g_can[gunid].curpf ,TCU_STATUS_STARTUP_COMPLETE_RESPONSE);

		if (g_can[gunid].ms_cur_recv
				>=cha2tcu_tab[g_can[gunid].curpos].over * 1000) {
			if(g_u3[gunid].MX2==0)
			{
				printf("启动充电成功！！！！！\r\n");
				g_can[gunid].state = WAIT_CHARGEING2;
			}
			else
				g_can[gunid].state = TCU_READY;
			g_can[gunid].ms_cur_recv = 0;
			g_can[gunid].ctrltype = 0;
			g_can[gunid].curpf=0;
			g_can[gunid].curpos=0xff;

		}
		else
		{
			FinStartStopBack(gunid,TCU_STATUS_STARTUP_COMPLETE_RESPONSE);

		}
		break;
	case WAIT_CHARGEING2:
		if (getChargeState(gunid)== 1 )
		{
			g_can[gunid].state = WAIT_CHARGEING3;

		}
		g_can[gunid].ms_cur_recv = 0;
		break;
	case    WAIT_CHARGEING3:
		//	if (getChargeState(gunid) == 1 )
	{
		g_can[gunid].ms_cur_recv = 0;
	}
	//		else if(g_can[gunid].ms_cur_recv>=5 * 1000)
	//		{
	//						printf("注意：充电过程中控制器自行停止充电   \r\n");
	//						can_pro_debug1("摇信包=%.*a",8,a_can.data2main->gun[gunid].yx_data.yx_dc_pf22);
	//						finStopCharge_f(gunid,GO_STOP_CHA);
	//						g_can[gunid].state=TCU_READY;//枪状态返回充电待机状态
	//						g_can[gunid].ms_cur_recv = 0;
	//						g_can[gunid].ctrltype = 0;
	//						g_can[gunid].curpf=0;
	//						g_can[gunid].curpos=0xff;
	//		}

	break;


	case TCU_STOP_CHARGING:
		if (g_can[gunid].ms_cur_recv
				>= cha2tcu_tab[g_can[gunid].curpos].over * 1000) { ////发送停止充电应答超时（发送pf=03等待pf=04超时 返回充电待机）
			//			if (gpcan_para->firm_id == GW_SDANDARD) {
			//				gotoCHECK_VER(gunid, g_can[gunid].curpf, 0);
			//			}

			if (getChargeState(gunid) == 1) { //发送停止充电超时后，控制器仍然充电，返回充电状态

				g_can[gunid].state = WAIT_CHARGEING3;

			}else if(getChargeState(gunid) == 0) {
				finStopCharge_f(gunid, OVER_TIME_PF03);
				g_can[gunid].state = TCU_READY;

			}
			g_can[gunid].ms_cur_recv = 0;
			g_can[gunid].ctrltype = 0;
			g_can[gunid].curpf = 0;
			g_can[gunid].curpos = 0xff;
			g_can[gunid].ms_cur_send = 0;
		} else
			stop_charge(gunid, 2);

		break;

	case    WAIT_STOP:
		//	printf("WAIT_STOP  控制器返回04后等待停止完成帧pf=0x13过程\r\n");
		if(g_can[gunid].ms_cur_recv
				>= FIN_STOP_CHARGE * 1000)////等待控制器充电停止完成超时（等待pf=13超时）
		{
			//	gotoCHECK_VER(gunid,g_can[gunid].curpf,0);
			if (getChargeState(gunid) != 1) {//虽然未收到停止完成，但控制器已经停止充电，通知主控停止充电，tcu进入充电等待
				finStopCharge_f(gunid,OVER_TIME_PF13);
				g_can[gunid].state = TCU_READY;
				printf("111WAIT_STOP  控制器返回04后等待停止完成帧pf=0x13过程\r\n");
			} else {
				printf("222WAIT_STOP  控制器返回04后等待停止完成帧pf=0x13过程\r\n");
				g_can[gunid].state = WAIT_CHARGEING3;


			}
			g_can[gunid].ms_cur_recv = 0;
			g_can[gunid].ctrltype = 0;
			g_can[gunid].curpf = 0;
			g_can[gunid].curpos = 0xff;
			g_can[gunid].ms_cur_send = 0;
		}

		break;


	case    RESEND_STOP:
		//	printf("RESEND_STOP  控制器返回13后，TCU重复发送14帧5s\r\n");
		if (g_can[gunid].ms_cur_recv
				>= cha2tcu_tab[g_can[gunid].curpos].over * 1000)
		{
			g_can[gunid].state = TCU_READY;
			g_can[gunid].ms_cur_send = 0;
			g_can[gunid].ms_cur_recv = 0;
			g_can[gunid].ctrltype = 0;
			g_can[gunid].curpf=0;
			g_can[gunid].curpos=0xff;

		}
		else
			FinStartStopBack(gunid,TCU_STATUS_STOP_COMPLETE_RESPONSE);

		break;


	default:
		break;
	}

}

void  senderrtomain(u8 gunid)
{
	int i;
	memset(gpcan_para->data2main->gun[gunid].yx_data.yx_dc_pf22,0,8);
	memset(gpcan_para->data2main->gun[gunid].yx_data.yx_dc_pf23,0,8);
	gpcan_para->data2main->gun[gunid].yx_data.yx_dc_pf22[0]=gunid;
	gpcan_para->data2main->gun[gunid].yx_data.yx_dc_pf23[0]=gunid;
	for(i=0;i<32;i++)
		gpcan_para->data2main->gun[gunid].yc_data.dc.MX[i]=0;


	gpcan_para->outyx(gunid,
			(void*) &gpcan_para->data2main->gun[gunid].yx_data);  //送数据到主控

	gpcan_para->outyc(gunid,(void*)&gpcan_para->data2main->gun[gunid].yc_data);//.ac.MX[0]

}
void timed2Cha(u8 gunid)
{
	u8 pf=0;
	u8 heart_over_err=gpcan_para->data2main->errcode[gunid];
	static int numm[]={0,0,0,0,0,0,0,0};
	u8 chargestate=getChargeState(gunid);
	numm[gunid]++;
	if((numm[gunid]%20)==0 )
	{
		can_pro_debug("timed2Cha  gunid=%d",gunid);
		printf("\r\n\r\n第 %d号枪当前状态 state=%d  pf=%x  gpcan_para->data2main->errcode[gunid]=%d\r\n\r\n",gunid,g_can[gunid].state,g_can[gunid].curpf,gpcan_para->data2main->errcode[gunid]);

	}


	if((g_can[gunid].state <= TCU_READY ||  g_can[gunid].state==TCU_IDEL) && chargestate==1)
	{
		printf("\r\n\r\n第 %d号枪当前状态 state=%d 正在充电，停止充电！！！\n",gunid,g_can[gunid].state);
		g_can[gunid].state=TCU_STOP_CHARGING;//错误帧剩余发送时间
		stop_charge(gunid,2);
		g_can[gunid].ms_cur_recv = 0;
	}
	//	if(g_can[gunid].state == HEART_BEAT_FIRST )  xj_mqtt_connect000000000000000000000000000000
	//	{
	//		if(g_can[gunid].ms_heart_send >= cha2tcu_tab[g_can[gunid].heart_pos].dly)
	//		     canSendHeartFrame(gunid);
	//		return ;
	//	}


	if (g_can[gunid].state != TCU_IDEL){
		if (g_can[gunid].ms_heart_recv
				>= cha2tcu_tab[g_can[gunid].heart_pos].over*1000) {

			heart_over_err |= (1<<HEART_OVER_ERR);
			can_pro_debug1("出现can故障  出现can故障  心跳停止！！！！！！！！！！！！！！！！gunid=%d\r\n\r\n\r\n",gunid);
			if (g_can[gunid].ms_comm_recv>=COMM_CUTOFF*1000 || g_can[gunid].state <= TCU_READY)
				g_can[gunid].state = TCU_IDEL;

		}
		else if (g_can[gunid].ms_heart_send
				>= cha2tcu_tab[g_can[gunid].heart_pos].dly) {
			can_pro_debug1("00000000向控制器发送心跳包   g_can[%d].state=%d  g_can[%d].ms_heart_recv=%d",gunid,g_can[gunid].state,gunid,g_can[gunid].ms_heart_recv);
			//
			if(gunid==0)
				can_pro_debug("22222222向控制器发送心跳包   g_can[%d].state=%d  g_can[%d].ms_heart_recv=%d",gunid,g_can[gunid].state,gunid,g_can[gunid].ms_heart_recv);
			else
				can_pro_debug("333333333向控制器发送心跳包   g_can[%d].state=%d  g_can[%d].ms_heart_recv=%d",gunid,g_can[gunid].state,gunid,g_can[gunid].ms_heart_recv);
			canSendHeartFrame(gunid);

		}

	}
	else {
		//		if (g_can[gunid].ms_heart_recv >=  (cha2tcu_tab[g_can[gunid].heart_pos].over+8)*1000)
		//		{
		//can_pro_debug1("gunid=%d  向控制器发第一个送心跳包\r\n", gunid);
		g_can[gunid].state = HEART_BEAT_FIRST;
		g_can[gunid].ms_yc_recv =0;
		g_can[gunid].ms_yx_recv=0;
		g_can[gunid].err_code_all =0;
		g_can[gunid].ms_heart_recv =0;
		canSendHeartFrame(gunid);
		printf("通信中断或上电gunid=%d  向控制器发第一个送心跳包完成\r\n", gunid);

		//	}
		return;
	}

	if(g_can[gunid].ms_err_send>=cha2tcu_tab[g_can[gunid].err_pos].dly  && g_can[gunid].err_code_all  != 0)
	{
		SendErr2Cha(gunid,g_can[gunid].err_code_all);
	}


	if (g_can[gunid].state_ctrl == CTRL_PW_EN
			&& g_can[gunid].ms_fk_send
			>= cha2tcu_tab[g_can[gunid].fk_pos].dly && g_can[gunid].ms_fk_recv<cha2tcu_tab[g_can[gunid].fk_pos].over*1000)
	{
		can_pro_debug("打印控制状态state_ctrl=%d ms_fk_send=%d,dly=%d\r\n",g_can[gunid].state_ctrl,g_can[gunid].ms_fk_send,cha2tcu_tab[g_can[gunid].fk_pos].dly);
		g_can[gunid].ms_fk_send = 0;
		adjust_pw(gunid);
	}

	else if(g_can[gunid].ms_fk_recv<=cha2tcu_tab[g_can[gunid].fk_pos].over*1000)
	{
		g_can[gunid].state_ctrl = CTRL_PW_NORMAL;
		g_can[gunid].ms_fk_send = 0;
		g_can[gunid].ms_fk_recv = 0;
	}

	if(g_can[gunid].state>CONFIG_INFO_QUERY && g_can[gunid].state<TCU_IDEL )
	{

		if(g_can[gunid].ms_yc_recv >=YC_OVER*1000  &&((heart_over_err & (1<<YC_OVER_ERR))==0))
		{
			//		 printf("11111111111111出现can故障  出现can故障！！！！！！！！！！！！！！！！g_can[gunid].heart_over_err=%d g_can[gunid].ms_yc_recv=%d \r\n\r\n\r\n",g_can[gunid].heart_over_err,g_can[gunid].ms_yc_recv);
			if(gpcan_para->type==DC)
			{
				pf=CTL_DATA_DC_TELEMETRY;
			}
			else
			{
				pf=CTL_DATA_AC_TELEMETRY;
			}
			heart_over_err |=(1<<YC_OVER_ERR);
			if((g_can[gunid].state>TCU_START_CHARGING && g_can[gunid].state<TCU_STOP_CHARGING)  || (chargestate==1 && g_can[gunid].state!= TCU_STOP_CHARGING && g_can[gunid].state!= WAIT_STOP ))
			{
				printf("充电中出现摇测超时，  state=%d\r\n",g_can[gunid].state);
				//				g_can[gunid].state=TCU_STOP_CHARGING;
				//				stop_charge(gunid,2);
				//				g_can[gunid].ms_cur_recv = 0;
			}
			else
			{
				printf("出现摇测超时，state=%d\r\n",g_can[gunid].state);
				gotoCHECK_VER(gunid,pf,1);//返回匹配开始
			}
		}

		if(g_can[gunid].ms_yx_recv >=YX_OVER*1000  && ((heart_over_err & (1<<YX_OVER_ERR))==0))
		{

			if(gpcan_para->type==DC)
			{
				pf=CTL_DATA_DC_TELESIGNAL_1;
			}

			else
			{
				pf=CTL_DATA_AC_TELESIGNAL_1;
			}

			heart_over_err |=(1<<YX_OVER_ERR);

			if((g_can[gunid].state>TCU_START_CHARGING && g_can[gunid].state<TCU_STOP_CHARGING)  || (getChargeState(gunid)==1 && g_can[gunid].state!= TCU_STOP_CHARGING && g_can[gunid].state!= WAIT_STOP ))
			{
				printf("充电中出现摇信超时，  state=%d\r\n",g_can[gunid].state);
				//				g_can[gunid].state=TCU_STOP_CHARGING;
				//				stop_charge(gunid,2);
				//				g_can[gunid].ms_cur_recv = 0;
			}
			else
			{
				printf("出现摇信超时，  state=%d\r\n",g_can[gunid].state);
				gotoCHECK_VER(gunid,pf,1);//
			}


		}


		if(g_can[gunid].ms_yc_send >=cha2tcu_tab[g_can[gunid].yc_pos].dly &&  g_can[gunid].state >=TCU_READY  && g_can[gunid].state!=TCU_IDEL)
		{
			SendYc_pf21(gunid);
		}
	}
	//111出现can故障

	if(heart_over_err>0)
		printf("tt000000000出现can故障  出现can故障can_state_err=0X%02X  gpcan_para->data2main->errcode[%d]=%d \n",heart_over_err,gunid,gpcan_para->data2main->errcode[gunid]);
	if(heart_over_err>0 && gpcan_para->data2main->errcode[gunid]==0)
	{
		printf("tt11111111111出现can故障  出现can故障\n");
		gpcan_para->data2main->errcode[gunid]=heart_over_err;
		senderrtomain(gunid);
	}
	else if(heart_over_err!=gpcan_para->data2main->errcode[gunid])
	{
		gpcan_para->data2main->errcode[gunid]=heart_over_err;
	}

}
void initcan(void)
{

	int i;
	libcan_t can_tem={TCU_IDEL,0,0,0xffff,0xffff,0xffff,0xffff,0xffff,0,0,0,0,0,0,0,0,0,0	,0,0,0,0,0,0};

	OverTimeErr  tab_err[]={	{TCU_CMD_SEND_CHARGE_PARAM,OVTM_DOWN_CHA_PARA,0},	//下发充电参数应答超时
			{CTL_CMD_START_RESPONSE ,OVTM_START_CHARGE,0},			//充电启动命令应答超时
			{CTL_STATUS_STARTUP_COMPLETE,OVTM_FINSTART_CHARGE,0},	//等待充电启动完成状态超时
			{CTL_CMD_STOP_RESPONSE,OVTM_STOP_CHARGE,0},				//充电停止命令应答超时
			{CTL_STATUS_STOP_COMPLETE,OVTM_FINSTOP_CHARGE,0},		//等待充电停止完成状态超时
			{CTL_CMD_TIME_SET,OVTM_SETTIME_CHA,0},					//对时操作应答超时
			{CTL_CMD_CHARGE_SERVER_FEEDBACK,OVTM_EN_DISEN_SERVER,0},//充电服务启停应答超时
			{CTL_CMD_ELE_LOCK_FEEDBACK,OVTM_CTRL_LOCK,0},			//电子锁控制应答超时
			{CTL_CMD_POWER_ADJUST_FEEDBACK,OVTM_CHANGE_PW,0} ,		//充电桩功率设置应答超时
			{TCU_CMD_CHARGE_CONFIG_INFO_QUERY,OVTM_CFG_INFO,0},	//充电桩配置信息查询应答超时
			{CTL_DATA_AC_TELESIGNAL_1,OVTM_AC_YX,0},				//交流遥信报文接收超时
			{CTL_DATA_DC_TELESIGNAL_1,OVTM_DC_YX,0},				//直流遥信报文接收超时
			{CTL_DATA_AC_TELEMETRY,OVTM_AC_YC,0},					//交流遥测报文接收超时
			{CTL_DATA_DC_TELEMETRY,OVTM_DC_YC,0},					//直流遥测报文接收超时
	};

	for(i=0;i<gpcan_para->gunnum;i++)//gpcan_para->gunnum
	{
		g_can[i]=can_tem;
		memcpy((u8*)&overTimeTable[i],(u8*)&tab_err[0],14*sizeof(OverTimeErr));
		g_can[i].fk_pos = TableSearch(TCU_CMD_POWER_ADJUST_CONTROL, (u8*) cha2tcu_tab,
				sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);

		g_can[i].heart_pos = TableSearch(TCU_HEART, (u8*) cha2tcu_tab,
				sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);//心跳定时发送


		g_can[i].err_pos = TableSearch(TCU_ERROR_STATUS, (u8*) cha2tcu_tab,
				sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);//超时故障发送定时发送

		//TCU遥测数据定时发送
		if(gpcan_para->type==DC && fac31==0)
			g_can[i].yc_pos=TableSearch(TCU_DATA_DC_TELEMETRY, (u8*) cha2tcu_tab,
					sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);
		else
			g_can[i].yc_pos=TableSearch(TCU_DATA_AC_TELEMETRY, (u8*) cha2tcu_tab,
					sizeof(Cha_TcuInstruction), ARRAY_LEN(cha2tcu_tab), 1);


		g_can[i].curpos=0xff;

		g_can[i].ms_heart_recv=(cha2tcu_tab[g_can[i].heart_pos].over+7)*1000;
		multFrame[i].dataIndex = 0;
		multFrame[i].frameIndex = 0;
		multFrame[i].frameSumCount = 0;
		multFrame[i].dataLen = 0;
		multFrame[i].lastFrameDataLen = 0;
		multFrame[i].priPF = 0;
		memset(multFrame[i].multiFrameData,0,128);

		//		g_can[i].heart_over_err = 0;
		gpcan_para->data2main->errcode[i] = 0;

		g_can[i].state=TCU_IDEL;

	}

}

